Commit 19856f48 authored by Mark Winter's avatar Mark Winter

Merge branch remote tracking branch 'opensource/master' into master

# Conflicts:
#	src/MATLAB/+Dev/GitStatus.m
#	src/MATLAB/+Dev/LoadVersion.m
#	src/MATLAB/+ImUtils/ConvertType.m
#	src/MATLAB/+MicroscopeData/+Helper/ParseReaderInputs.m
#	src/MATLAB/+MicroscopeData/+Original/+BioFormats/GetImages.m
#	src/MATLAB/+MicroscopeData/+Original/+BioFormats/GetMetadata.m
#	src/MATLAB/+MicroscopeData/Reader.m
#	src/MATLAB/+MicroscopeData/ReaderH5.m
parents d13a5f91 a112f2f8
No preview for this file type
No preview for this file type
......@@ -52,7 +52,7 @@ function changeLines = GitStatus(chkPath,chkFiles)
cFiles = changeFiles(bMatched);
for i=1:length(cFiles)
changeLines = [changeLines; {'Possible MEX dependency - ' cFiles{i}}];
changeLines = [changeLines; {['Possible MEX dependency - ' cFiles{i}]}];
end
end
end
......
function verInfo = LoadVersion()
%% Use compiled VersionInfo function when deployed
verInfo = [];
if ( isdeployed )
verInfo = Dev.VersionInfo();
return;
......@@ -7,9 +8,8 @@ function verInfo = LoadVersion()
%% Try to load version tag and branch using git
bFoundGit = Dev.SetupGit();
verInfo = [];
if ( bFoundGit )
chkVerInfo = gitVersionInfo();
verInfo = gitVersionInfo();
end
%% Use fallback file for name (set by Dev.MakeVersion)
......@@ -21,15 +21,13 @@ function verInfo = LoadVersion()
return;
end
if ( isempty(chkVerInfo) )
if ( isempty(verInfo) )
fprintf('WARNING: Could not find git directory, using fallback %s\n', fallbackFile);
chkVerInfo = fallbackVerInfo;
verInfo = fallbackVerInfo;
end
% Always use the name from fallback file
chkVerInfo.name = fallbackVerInfo.name;
verInfo = chkVerInfo;
verInfo.name = fallbackVerInfo.name;
end
%% Read fallback json version file
......@@ -74,7 +72,7 @@ function verInfo = gitVersionInfo()
verInfo = struct(...
'name',{repoName},...
'majorVersion',{majorVer},...
'minorVersion',{minorVer+1},...
'minorVersion',{floor(minorVer)+1},...
'branchName',{branchName},...
'buildNumber',{'UNKNOWN'},...
'buildMachine',{'UNKNOWN'},...
......
......@@ -13,12 +13,38 @@ if (~exist('normalize','var') || isempty(normalize))
normalize = 0;
end
w = whos('imageIn');
if (strcmpi(w.class,typ) && ~normalize)
imageOut = imageIn;
return
end
if (~strcmpi(typ,'logical'))
imageOut = zeros(size(imageIn),typ);
else
imageOut = false(size(imageIn));
end
% deal with images that come in as 16 bit but are really a lesser bit depth
if (strcmpi(w.class,'uint16'))
imMax = max(imageIn(:));
maxTypes = [2^8-1,2^10-1,2^12-1];
isBigger = maxTypes < double(imMax);
if (isBigger(3))
% truly a 16 bit image
% do nothing
elseif (isBigger(2))
% is really a 12 bit image
imageIn = single(imageIn)./single(maxTypes(3));
elseif (isBigger(1))
% is really a 10 bit image
imageIn = single(imageIn)./single(maxTypes(2));
else
% is really a 8 bit image
imageIn = single(imageIn)./single(maxTypes(1));
end
end
if (normalize)
for t=1:size(imageIn,5)
for c=1:size(imageIn,4)
......@@ -39,7 +65,7 @@ if (normalize)
case 'int16'
imageOut(:,:,:,c,t) = im2int16(imTemp);
case 'uint32'
imageOut(:,:,:,c,t) = im2uint32(imTemp);
imageOut(:,:,:,c,t) = uint32(imTemp*(2^32-1));
case 'int32'
imageOut(:,:,:,c,t) = im2int32(imTemp);
case 'single'
......@@ -54,7 +80,6 @@ if (normalize)
end
end
else
w = whos('imageIn');
switch w.class
case 'single'
imageIn = convertToMaxOfOne(imageIn,w.class);
......
......@@ -37,7 +37,7 @@ function renameStruct = BuildRenameStruct(imageName)
[startMatch,tokMatch] = regexpi(fileName, paramPattern, 'start','tokens');
% If there are multiple matches to the parameter type, take only the one that's furthest in the name.
bFoundParams = cellfun(@(x)(~isempty(x)),startMatch);
bFoundParams = cellfun(@(x)(~isempty(x)), startMatch);
validStarts = cellfun(@(x)(x(end)), startMatch(bFoundParams));
validParams = cellfun(@(x)(x{end}{1}), tokMatch(bFoundParams), 'UniformOutput',false);
......
......@@ -27,25 +27,34 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [bNeedsExport,bWriteable,renameStruct] = CheckExportImages(rootDir,fileName)
function [bNeedsExport,bTifSequence,bInPlace,renameStruct] = CheckExportImages(rootDir,filename)
bNeedsExport = false;
bWriteable = false;
bTifSequence = false;
bInPlace = false;
renameStruct = [];
[~,chkName,chkExt] = fileparts(fileName);
[~,chkName,chkExt] = fileparts(filename);
if ( any(strcmpi(chkExt,{'.tif','.tiff'})) )
jsonList = dir(fullfile(rootDir,[chkName '*.json']));
if ( ~isempty(jsonList) )
return;
end
renameStruct = Load.BuildRenameStruct(fileName);
bTifSequence = checkSequence(rootDir, filename);
renameStruct = Load.BuildRenameStruct(filename);
end
bWriteable = ~isempty(renameStruct) && checkWriteable(rootDir);
bInPlace = ~isempty(renameStruct) && checkWriteable(rootDir);
bNeedsExport = true;
end
function bSequence = checkSequence(rootDir, filename)
fileBlob = regexprep(filename, '\d+', '*');
fileList = dir(fullfile(rootDir,fileBlob));
bSequence = (length(fileList) > 1);
end
function bCanWrite = checkWriteable(rootDir)
bCanWrite = false;
......
......@@ -22,14 +22,15 @@
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [subPaths,needsExport,renamable] = CheckFolderExport(rootDir)
[subPaths,needsExport,renamable] = recursiveCheckExport(rootDir,'');
function [subPaths,needsExport,renamable,ambiguous] = CheckFolderExport(rootDir)
[subPaths,needsExport,renamable,ambiguous] = recursiveCheckExport(rootDir,'');
end
function [subPaths,needsExport,renamable] = recursiveCheckExport(rootDir,subDir)
function [subPaths,needsExport,renamable,ambiguous] = recursiveCheckExport(rootDir,subDir)
subPaths = {};
needsExport = false(0);
renamable = false(0);
ambiguous = false(0);
dirList = dir(fullfile(rootDir,subDir));
......@@ -59,6 +60,7 @@ function [subPaths,needsExport,renamable] = recursiveCheckExport(rootDir,subDir)
subPaths = cellfun(@(x)(fullfile(subDir,x)),jsonNames(bValid),'UniformOutput',false);
needsExport = false(nnz(bValid),1);
renamable = false(nnz(bValid),1);
ambiguous = false(nnz(bValid),1);
end
%% Handle folders of TIFs that don't require export or are renamable stacks
......@@ -68,11 +70,18 @@ function [subPaths,needsExport,renamable] = recursiveCheckExport(rootDir,subDir)
tifNames = filenames(bTIF);
if ( ~isempty(tifNames) )
% If these appear to be renameable tifs don't bother with subdirectories
[bNeedsExport,bWriteable,renameStruct] = Load.CheckExportImages(fullfile(rootDir,subDir),tifNames{1});
[bNeedsExport,bSequence,bInPlace,renameStruct] = Load.CheckExportImages(fullfile(rootDir,subDir),tifNames{1});
if ( bSequence && isempty(renameStruct) )
subPaths = {fullfile(subDir,tifNames{1})};
needsExport = bNeedsExport;
ambiguous = true;
return;
end
if ( ~isempty(renameStruct) )
subPaths = {fullfile(subDir,tifNames{1})};
needsExport = bNeedsExport;
renamable = bWriteable;
renamable = bInPlace;
return;
end
......@@ -86,15 +95,17 @@ function [subPaths,needsExport,renamable] = recursiveCheckExport(rootDir,subDir)
subPaths = [subPaths; cellfun(@(x)(fullfile(subDir,x)),exportNames,'UniformOutput',false)];
needsExport = [needsExport; true(length(exportNames),1)];
renamable = [renamable; false(length(exportNames),1)];
ambiguous = [ambiguous; false(length(exportNames),1)];
end
%% Deal with further subdirectories
for i=1:length(pathList)
nextSubDir = fullfile(subDir,pathList(i).name);
[newPaths,chkExport,chkRename] = recursiveCheckExport(rootDir,nextSubDir);
[newPaths,chkExport,chkRename,chkAmbiguous] = recursiveCheckExport(rootDir,nextSubDir);
subPaths = [subPaths; newPaths];
needsExport = [needsExport; chkExport];
renamable = [renamable; chkRename];
ambiguous = [ambiguous; chkAmbiguous];
end
end
......@@ -23,7 +23,7 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function jsonPath = ExportImages(exportDir, inRoot,inFilename)
[~,imD] = MicroscopeData.Original.Convert2Tiffs(inRoot,inFilename, exportDir, true, false);
[~,imD] = MicroscopeData.Original.ConvertData(inRoot,inFilename, exportDir, false, true, false);
if ( length(imD) > 1 )
[~,imName] = fileparts(inFilename);
exportDir = fullfile(exportDir,imName);
......
......@@ -25,7 +25,7 @@
function exportRoot = FolderExport(rootDir)
exportRoot = rootDir;
[subPaths,needsExport,renamable] = Load.CheckFolderExport(rootDir);
[subPaths,needsExport,renamable,ambiguous] = Load.CheckFolderExport(rootDir);
if ( isempty(subPaths) )
return;
end
......@@ -35,6 +35,17 @@ function exportRoot = FolderExport(rootDir)
return;
end
if ( any(ambiguous) )
exportRoot = '';
msgbox({'The directories appear to contain image sequences.',...
'Image sequences must conform to LEVER name guidelines.',...
'Please use IrfanView or another tool to rename the images.',...
'',...
'Image name format: <DatasetName>_c%02d_t%04d_z%04d.tif'},...
'Export Error', 'Warn');
return;
end
% Allow an inplace update if all exports are renamable
exportRenames = renamable(needsExport);
exportPaths = subPaths(needsExport);
......
......@@ -23,7 +23,9 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function jsonPath = ImageExportDialog(rootDir,filename)
[bNeedsExport,bWriteable,renameStruct] = Load.CheckExportImages(rootDir,filename);
jsonPath = '';
[bNeedsExport,bSequence,bInPlace,renameStruct] = Load.CheckExportImages(rootDir,filename);
if ( ~bNeedsExport )
[~,chkName] = fileparts(filename);
jsonList = dir(fullfile(rootDir,[chkName '*.json']));
......@@ -31,7 +33,17 @@ function jsonPath = ImageExportDialog(rootDir,filename)
return;
end
exportDir = Load.ExportLocationDialog(rootDir, bWriteable);
if ( bSequence && isempty(renameStruct) )
msgbox({'The selected image appears to be part of an image sequence.',...
'Image sequences must conform to LEVER name guidelines.',...
'Please use IrfanView or another tool to rename the sequence.',...
'',...
'Image name format: <DatasetName>_c%02d_t%04d_z%04d.tif'},...
'Export Error', 'Warn');
return;
end
exportDir = Load.ExportLocationDialog(rootDir, bInPlace);
if ( isempty(exportDir) )
return;
end
......
......@@ -25,9 +25,11 @@ function argStruct = ParseReaderInputs(varargin)
addParameter(p,'chanList',[], @(x)(validOrEmpty(@isvector,x)));
addParameter(p,'timeRange',[], @(x)(validOrEmpty(@(y)(numel(y)==2),x)));
addParameter(p,'roi_xyz',[], @(x)(validOrEmpty(@(y)(all(size(y)==[2,3])),x)));
addParameter(p,'getMIP',false,@islogical);
addParameter(p,'outType',[], @(x)(validOrEmpty(@(y)(any(strcmp(y,dataTypeLookup))),x)));
addParameter(p,'normalize',false,@islogical);
addParameter(p,'imVersion','Original',@ischar);
addParameter(p,'verbose',false, @islogical);
addParameter(p,'prompt',[], @(x)(validOrEmpty(@islogical,x)));
......
......@@ -28,6 +28,10 @@ else
end
end
if (length(seriesImages)==1)
seriesImages = seriesImages{1};
end
prgs.ClearProgress();
end
......
......@@ -17,7 +17,7 @@ if (bfReader.getSeriesCount()>1)
onlyOneSeries = false;
end
for series=0:bfReader.getSeriesCount()-1;
for series=0:bfReader.getSeriesCount()-1
bfReader.setSeries(series);
imageData = [];
......@@ -109,6 +109,8 @@ for series=0:bfReader.getSeriesCount()-1;
size(imageData.TimeStampDelta,3)~=imageData.NumberOfFrames)
imageData = rmfield(imageData,'TimeStampDelta');
end
imageData.imageDir = fileparts(char(bfReader.getCurrentFile));
seriesMetadata{series+1} = imageData;
......@@ -117,6 +119,10 @@ end
prgs.ClearProgress();
if (length(seriesMetadata)==1)
seriesMetadata = seriesMetadata{1};
end
if (nargout>1)
varargout{1} = omeMetadata;
end
......
function [ im, imD ] = ConvertData( imDir, imName, outDir, makeH5, overwrite, quiet, cleanName)
%[ im, imD ] = MicroscopeData.Original.ConvertData( imDir, imName, outDir, makeH5, overwrite, quiet, cleanName)
im = [];
imD = [];
if (~exist('makeH5','var') || isempty(makeH5))
makeH5 = false;
end
if (~exist('overwrite','var') || isempty(overwrite))
overwrite = false;
end
if (~exist('quiet','var') || isempty(quiet))
quiet = false;
end
if (~exist('imDir','var') || isempty(imDir))
imDir = '.';
end
if (~exist('imName','var') || isempty(imName))
[imName,imDir,~] = uigetfile('*.*','Choose a Microscope File to Convert');
if (imName==0)
warning('Nothing read');
return
end
end
if (~exist('outDir','var') || isempty(outDir))
outDir = uigetdir('.','Choose a folder to output to');
if (outDir==0)
warning('No where to write!');
return
end
end
if (~exist('cleanName','var') || isempty(cleanName))
cleanName = false;
end
if (cleanName)
outDir = MicroscopeData.Helper.CreateUniqueWordedPath(outDir);
end
[~,name,~] = fileparts(imName);
if (~exist(fullfile(outDir,name),'dir') || overwrite)
imD = MicroscopeData.Original.ReadMetadata(imDir,imName);
if ( isempty(imD) )
return;
end
[~,datasetName,~] = fileparts(imName);
if (length(imD)>1)
if (cleanName)
datasetName = MicroscopeData.Helper.SanitizeString(datasetName);
end
outDir = fullfile(outDir,datasetName);
end
% Don't overwrite images that already exist
if (exist(fullfile(outDir,imD{1}.DatasetName),'dir') && ~overwrite)
return;
end
im = MicroscopeData.Original.ReadImages(imDir,imName);
prgs = Utils.CmdlnProgress(length(imD),quiet,['Writing out ',datasetName]);
if (~iscell(imD))
imDcell = {};
imDcell{1} = imD;
else
imDcell = imD;
end
for i=1:length(imD)
if (cleanName)
imD{i}.DatasetName = MicroscopeData.Helper.SanitizeString(imD{i}.DatasetName);
end
if (~exist(fullfile(outDir,imD{i}.DatasetName),'dir') || overwrite)
if (makeH5)
MicroscopeData.WriterH5(im{i},fullfile(outDir,imD{i}.DatasetName),'imageData',imD{i},'verbose',~quiet);
else
MicroscopeData.Writer(im{i},fullfile(outDir,imD{i}.DatasetName),imD{i},[],[],[],~quiet);
end
end
prgs.PrintProgress(i);
end
prgs.ClearProgress(quiet);
cmd = sprintf('dir "%s" /B /O:N /A:D > "%s"',outDir,fullfile(outDir,'list.txt'));
system(cmd);
end
end
......@@ -8,55 +8,66 @@
% roi_xyz - x,y,z min and max roi to read
% outType - Desired output type, conversion is applied if different from image
% normalize - Normalize images on [0,1] per frame before conersion to output type
% imVersion - open the version of the image (e.g. Original, MIP, Processed)
% Default is 'Original'
% getMIP - return only a 2D image. A precomputed Maximum Intensity
% Projection (MIP) will be returned if the orignal was 3D
% verbose - Display verbose output and timing information
% prompt - False to completely disable prompts, true to force prompt, leave unspecified or empty for default prompt behavior
% promptTitle - Open dialog title in the case that prompting is required
function [im, imD] = Reader(varargin)
im = [];
imD = [];
readerTic = tic;
im = [];
dataTypeLookup = {'uint8';'uint16';'uint32';'uint64';
'int8';'int16';'int32';'int64';
'single';'double';
'logical'};
args = MicroscopeData.Helper.ParseReaderInputs(varargin{:});
args = MicroscopeData.Helper.ParseReaderInputs(varargin{:});
loadPath = '';
if ( ~isempty(args.imageData) )
loadPath = args.imageData.imageDir;
elseif ( ~isempty(args.path) )
loadPath = args.path;
end
loadPath = '';
if ( ~isempty(args.imageData) )
loadPath = args.imageData.imageDir;
elseif ( ~isempty(args.path) )
loadPath = args.path;
end
if ( args.prompt )
imD = MicroscopeData.ReadMetadata(loadPath,args.prompt,args.promptTitle);
elseif ( isempty(args.imageData) )
imD = MicroscopeData.ReadMetadata(loadPath,args.prompt,args.promptTitle);
else
imD = args.imageData;
end
if ( args.prompt )
imD = MicroscopeData.ReadMetadata(loadPath,args.prompt,args.promptTitle);
elseif ( isempty(args.imageData) )
imD = MicroscopeData.ReadMetadata(loadPath,args.prompt,args.promptTitle);
else
imD = args.imageData;
end
if (isempty(imD))
warning('No image read!');
return
end
if (isempty(imD))
warning('No image read!');
return
end
imPath = imD.imageDir;
hdf5File = fullfile(imPath,[imD.DatasetName '.h5']);
if ( exist(hdf5File,'file') )
[im,imD] = MicroscopeData.ReaderH5('imageData',imD, 'chanList',args.chanList, 'timeRange',args.timeRange, 'roi_xyz',args.roi_xyz, 'getMIP',args.getMIP,...
'outType',args.outType, 'normalize',args.normalize, 'imVersion',args.imVersion, 'verbose',args.verbose, 'prompt',false);
else
imPath = imD.imageDir;
hdf5File = fullfile(imPath,[imD.DatasetName '.h5']);
if ( exist(hdf5File,'file') )
[im,imD] = MicroscopeData.ReaderH5('imageData',imD, 'chanList',args.chanList, 'timeRange',args.timeRange, 'roi_xyz',args.roi_xyz,...
'outType',args.outType, 'normalize',args.normalize, 'verbose',args.verbose, 'prompt',false);
return;
end
tifFile = fullfile(imPath,sprintf('%s_c%02d_t%04d_z%04d.tif',imD.DatasetName,1,1,1));
if ( exist(tifFile,'file'))
[im,imD] = MicroscopeData.ReaderTIF('imageData',imD, 'chanList',args.chanList, 'timeRange',args.timeRange, 'roi_xyz',args.roi_xyz,...
'outType',args.outType, 'normalize',args.normalize, 'verbose',args.verbose, 'prompt',false);
tifFile = fullfile(imPath,sprintf('%s_c%02d_t%04d_z%04d.tif',imD.DatasetName,1,1,1));
if ( exist(tifFile,'file') )
[im,imD] = MicroscopeData.ReaderTIF('imageData',imD, 'chanList',args.chanList, 'timeRange',args.timeRange, 'roi_xyz',args.roi_xyz,...
'outType',args.outType, 'normalize',args.normalize, 'verbose',args.verbose, 'prompt',false);
return;
end
if (args.getMIP && size(im,3)>1)
imMIP = zeros(size(im,1),size(im,2),1,size(im,4),size(im,5),'like',im);
for t=1:imD.NumberOfFrames
for c=1:imD.NumberOfChannels
imMIP(:,:,1,c,t) = max(im(:,:,:,c,t),[],3);
end
end
im = imMIP;
end
end
end
warning('No supported image type found!');
if (isempty(im))
warning('No supported image type found!');
end
end
This diff is collapsed.
% WriterH5(im, path, varargin)
%
% Optional Parameters (Key,Value pairs):
%
% imageData - Input metadata, if specified, the optional path argument is ignored
% chanList - List of channels to write
% timeRange - Range min and max times to write
% roi_xyz - x,y,z min and max roi to write
% imVersion - open the version of the image (e.g. Original, MIP, Processed)
% Default is 'Original'
% verbose - Display verbose output and timing information
function WriterH5(im, varargin)
dataTypeLookup = {'uint8';'uint16';'uint32';'uint64';
'int8';'int16';'int32';'int64';
'single';'double';
'logical'};
dataTypeSize = [1;2;4;8;
1;2;4;8;
4;8;
1];
p = inputParser();
p.StructExpand = false;
% This is ridiculous, but we assume that the optional path is specified if
% length(varargin) is odd
if ( mod(length(varargin),2) == 1 )
addOptional(p,'path','',@ischar);
else
addParameter(p,'path','',@ischar);
end
addParameter(p,'datasetName',[],@ischar);
addParameter(p,'imageData',[],@isstruct);
addParameter(p,'chanList',[],@isvector);
addParameter(p,'timeRange',[],@(x)(numel(x)==2));
addParameter(p,'roi_xyz',[],@(x)(size(x)==[2,3]));
addParameter(p,'imVersion','Original',@ischar);
addParameter(p,'verbose',false,@islogical);
parse(p,varargin{:});
args = p.Results;
outDir = '';
datasetName = '';
if ( ~isempty(args.path) )
[outDir,chkFile,chkExt] = fileparts(args.path);
if ( ~isempty(chkExt) )
datasetName = chkFile;
else
outDir = args.path;
end
end
if ( ~isempty(args.datasetName) )
datasetName = args.datasetName;
end
if ( isempty(args.imageData) && isempty(datasetName) )
error('Either imageData, a datasetName, or a full file path must be provided!');
end
if ( isempty(args.imageData) )
args.imageData.DatasetName = datasetName;
chkSize = size(im);
args.imageData.Dimensions = Utils.SwapXY_RC(chkSize(1:3));
args.imageData.NumberOfChannels = chkSize(4);
args.imageData.NumberOfFrames = chkSize(5);
args.imageData.PixelPhysicalSizes = [1.0, 1.0, 1.0];
elseif ( ~isempty(datasetName) )
args.imageData.DatasetName = datasetName;
end
% Remove any quotes from the dataset name
args.imageData.DatasetName = strrep(args.imageData.DatasetName,'"','');
w = whos('im');
typeIdx = find(strcmp(w.class,dataTypeLookup));
if ( ~isempty(typeIdx) )
bytes = dataTypeSize(typeIdx);
else
error('Unsuported pixel type!');
end
if (~isfield(args.imageData,'PixelFormat'))
args.imageData.PixelFormat = w.class;
end
if ( isempty(outDir) )
outDir = '.';
end
outDir = strrep(outDir, '"','');
% fix if image type if the image is different
if (~isfield(args.imageData,'PixelFormat'))
args.imageData.PixelFormat = class(im);
elseif (~strcmp(args.imageData.PixelFormat,class(im)))
args.imageData.PixelFormat = class(im);
end
MicroscopeData.CreateMetadata(outDir,args.imageData,~args.verbose);
if ( isempty(args.chanList) )
args.chanList = 1:args.imageData.NumberOfChannels;
end
if ( isempty(args.timeRange) )
args.timeRange = [1 args.imageData.NumberOfFrames];
end
if ( isempty(args.roi_xyz) )
args.roi_xyz = [1 1 1; args.imageData.Dimensions];
end
if ( max(args.chanList) > args.imageData.NumberOfChannels)
error('A value in chanList is greater than the number of channels in the image data!');
end
if ( args.timeRange(2) > args.imageData.NumberOfFrames )
error('Specified time range is larger than the total number of frames.');
end
if ( any(args.roi_xyz(2,:) > args.imageData.Dimensions) )
error('Specified roi is larger than imageData size.');
end
if ( size(im,4)~=length(args.chanList) )
error('There are %d channels and %d channels to be written!',size(im,4),length(args.chanList));
end
tic
%save metadata for the type we want not the type we have to store
if (strcmp(args.imageData.PixelFormat,'logical'))