text:
function [outputMovie, movieDims, nPixels, nFrames] = loadMovieList(movieList, varargin)
	% [outputMovie, movieDims, nPixels, nFrames] = loadMovieList(movieList, varargin)
	%
	% Load movies, automatically detects type (avi, tif, or hdf5) and concatenates if multiple movies in a list.
	% 	NOTE:
	% 		The function assumes input is 2D time series movies with [x y frames] as dimensions
	% 		If movies are different sizes, use largest dimensions and align all movies to top-left corner.
	%
	% Biafra Ahanonu
	% started: 2013.11.01
	%
	% Inputs
	% 	movieList = either a char string containing a path name or a cell array containing char strings, e.g. 'pathToFile' or {'path1','path2'}
	%
	% Outputs
	% 	outputMovie - [x y frame] matrix.
	% 	movieDims - structure containing x,y,z information for the movie.
	% 	nPixels - total number of pixels in the movie across all frames.
	% 	nFrames - total number of frames in the movie depending on user requests in option.frameList.
	%
	% Options (input as Name-Value with Name = options.(Name))
	%	% Int vector: list of specific frames to load.
	%	options.frameList = [];
	%	% Str: path to MAT-file to load movie into, e.g. when conducting processing on movies that are larger than RAM.
	%	options.matfile = '';
	%	% Str: Variable name for movie to store MAT-file in. DO NOT CHANGE for the moment.
	%	options.matfileVarname = 'outputMovie';
	%	% Cell array of str: list of supported file types, in general DO NOT change.
	%	options.supportedTypes = {'.h5','.hdf5','.tif','.tiff','.avi',...
	%		'.nwb',... % Neurodata Without Borders format
	%		'.isxd',... % Inscopix format
	%		'.oir',... % Olympus formats
	%		'.czi','.lsm'... % Zeiss formats
	%	};
	%	% Str: movie type.
	%	options.movieType = 'tiff';
	%	% Str: hierarchy name in HDF5 file where movie data is located.
	%	options.inputDatasetName = '/1';
	%	% Str: default NWB hierarchy names in HDF5 file where movie data is located, will look in the order indicates
	%	options.defaultNwbDatasetName = {'/acquisition/TwoPhotonSeries/data'};
	%	% Str: fallback hierarchy name, e.g. '/images'
	%	options.inputDatasetNameBackup = [];
	%	% Binary: 1 = convert file movie to double, 0 = keep original format.
	%	options.convertToDouble = 0;
	%	% Str: 'single','double'
	%	options.loadSpecificImgClass = [];
	%	% Binary: 1 = read frame by frame to save memory, 0 = read continuous chunk.
	%	options.forcePerFrameRead = 0;
	%	% Binary: 1 = waitbar/progress bar is shown, 0 = no progress shown.
	%	options.waitbarOn = 1;
	%	% Binary: 1 = just return the movie dimensions, do not load the movie.
	%	options.getMovieDims = 0;
	%	% Binary: 1 = treat movies in list as continuous with regards to frames to extract.
	%	options.treatMoviesAsContinuous = 0;
	%	% Binary: 1 = whether to display info on command line.
	%	options.displayInfo = 1;
	%	% Binary: Whether to display diagnostic information
	%	options.displayDiagnosticInfo = 0;
	%	% Binary: 1 = display diagnostic information, 0 = do not display diagnostic information.
	%	options.displayWarnings = 1;
	%	% Matrix: Pre-specify the size, if need to get around memory re-allocation issues
	%	options.presetMovieSize = [];
	%	% Binary: 1 = avoid pre-allocating if single large matrix, saves memory. 0 = pre-allocate matrix.
	%	options.largeMovieLoad = 0;
	%	% Int: [numParts framesPerPart] number of equal parts to load the movie in
	%	options.loadMovieInEqualParts = [];
	%	% Binary: 1 = only check information for 1st file then populate the rest with identical information, useful for folders with thousands of TIF or other images
	%	options.onlyCheckFirstFileInfo = 0;
	%	% Binary: 1 = h5info, 0 = hdf5info. DO NOT rely on this, will be deprecated/eliminated soon.
	%	options.useH5info = 1;
	%	% Int: [] = do nothing, 1-3 indicates R,G,B channels to take from multicolor RGB AVI
	%	options.rgbChannel = [];
	%	% Int: Bio-Formats series number to load.
	%	options.bfSeriesNo = 1;
	%	% Int: Bio-Formats channel number to load.
	%	options.bfChannelNo = 1;
	%	% Cell array: Store file information, e.g. make TIFF reading faster.
	%	options.fileInfo = {};

	% changelog
		% 2014.02.14 [14:14:39] now can load non-monotonic lists for avi and hdf5 files.
		% 2014.03.27 - several updates to speed up function, fixed several assumption issues (all movies same file type, etc.) and brought name scheme in line with other fxns
		% 2015.02.25 [15:32:10] fixed bug pertaining to treatMoviesAsContinuous not working properly if frameList was blank and only a single movie was input.
		% 2015.05.28 [02:39:51] bug fix with treatMoviesAsContinuous, the global frames weren't quite correct
		% 2016.02.23 [19:40:31] added in proper-ish ability to read in RGB grayscale AVI files
		% 2017.07.06 [20:13:53] improved getHdf5Info() subfxn to handle Jessica's HDF5 format in a more automatic fashion, e.g. if there is behavior or other group level data in the HDF5 file
		% 2018.02.16 [14:48:24] Fixed frame-by-frame HDF5 load being inefficient by using tmpMovie instead of loading directly into said movie
		% 2018.09.28 [16:49:29] HDF5 non-contiguous frame reading is faster, no looping since select multiple hyperslabs at once, see readHDF5Subset for more
		% 2019.01.16 [07:51:01] Added ISXD support (Inscopix format for v3+).
		% 2019.03.10 [19:28:47] Improve support for loading 1000s of TIF files by adding some performance improvements, ASSUMES that all tifs being loaded are from the same movie and have similar properties and dimensions. See options.onlyCheckFirstFileInfo.
		% 2019.06.06 [19:39:17] - Misc code fixes
		% 2019.10.07 [10:21:09] - Added h5info support and support for 16-bit float types.
		% 2019.10.09 [17:14:24] - Change dataset reading to handle HDF5 where main dataset is not a top-level directory OR it is a sub-directory that is not the only dataset in the HDF5.
		% 2020.04.05 [16:27:11] - Added check to support reading NWB as HDF5 file.
		% 2020.08.30 [10:16:08] - Change warning message output for HDF5 file of certain type.
		% 2020.08.31 [15:47:49] - Add option to suppress warnings.
		% 2020.10.19 [12:11:14] - Improved comments and options descriptions.
		% 2021.02.15 [11:55:36] - Fixed loading HDF5 datasetname that has only a single frame, loadMovieList would ask for 3rd dimension information that did not exist.
		% 2021.06.21 [10:22:32] - Added support for Bio-Formats compatible files, specifically Olympus (OIR) and Zeiss (CZI, LSM).
		% 2021.06.28 [16:57:27] - Added check that deals with users requesting more frames than are in the movie in the case where "options.largeMovieLoad==1" and a matrix is pre-allocated.
		% 2021.06.30 [12:26:12] - Added additional checks for frameList to remove if negative or zero along with additional checks during movie loading to prevent loading frames outside movie extent.
		% 2021.07.03 [08:55:06] - dims.three fix for reading tifs, esp. ImageJ >4GB.
		% 2021.08.08 [19:30:20] - Updated to handle CIAtah v4.0 switch to all functions inside ciapkg package.
		% 2021.08.13 [02:31:48] - Added HDF5 capitalized file extension.
        % 2021.08.26 [16:15:37] - Ensure that loadMovieList has all output arguments set no matter return conditions.
        % 2022.02.24 [10:24:28] - AVI now read(...,'native') is faster.
		% 2022.03.07 [15:56:58] - Speed improvements related to imfinfo calls.
		% 2022.03.13 [19:43:23] - Add option to load movie into a MAT-file.
		% 2022.03.23 [22:24:46] - Improve Bio-Formats support, including using bfGetPlane to partially load data along with adding ndpi support.
		% 2022.07.05 [21:21:35] - Add SlideBook Bio-Formats support. Remove local function getMovieFileType to force use of CIAtah getMovieFileType function. Updated getIndex call to avoid issues with certain Bio-Formats. Ensure getting correct Bio-Formats frames and loadMovieList output.
		% 2022.07.28 [18:44:47] - Hide TIF warnings.

	% TODO
		% OPEN
			% Bio-Formats
				% Allow outputting as a [x y c t] matrix to allow support for multiple color channels without needing to re-read file multiple times.
			% Determine file type by properties of file instead of extension (don't trust input...)
			% Remove all use of tmpMovie....
			% Add ability to degrade gracefully with HDF5 dataset names, so try several backup datasetnames if one doesn't work.
			% Allow fallbacks for HDF5 dataset name, e.g. if can't find /1, look for /images. Might never add this as it opens up dangers of loading the incorrect dataset if a user makes a mistake, better to give out a warning.
		% DONE
			% allow user to input frames that are global across several files, e.g. [1:500 1:200 1:300] are the lengths of each movie, so if input [650:670] in frameList, should grab 150:170 from movie 2 - DONE, see treatMoviesAsContinuous option.
			% verify movies are of supported load types, remove from list if not and alert user, should be an option (e.g. return instead) - DONE
			% MAKE tiff loading recognize frameList input. - DONE
			% Add preallocation by pre-reading each movie's dimensions - DONE

	import ciapkg.api.* % import CIAtah functions in ciapkg package API.

	% ========================
	% Int vector: list of specific frames to load.
	options.frameList = [];
	% Str: path to MAT-file to load movie into, e.g. when conducting processing on movies that are larger than RAM.
	options.matfile = '';
	% Str: Variable name for movie to store MAT-file in. DO NOT CHANGE for the moment.
	options.matfileVarname = 'outputMovie';
	% Cell array of str: list of supported file types, in general DO NOT change.
	options.supportedTypes = {'.h5','.hdf5','.tif','.tiff','.avi',...
		'.nwb',... % Neurodata Without Borders format
		'.isxd',... % Inscopix format
		'.oir',... % Olympus formats
		'.czi','.lsm'... % Zeiss formats
	};
	% Str: movie type.
	options.movieType = 'tiff';
	% Str: hierarchy name in HDF5 file where movie data is located.
	options.inputDatasetName = '/1';
	% Str: default NWB hierarchy names in HDF5 file where movie data is located, will look in the order indicates
	options.defaultNwbDatasetName = {'/acquisition/TwoPhotonSeries/data'};
	% Str: fallback hierarchy name, e.g. '/images'
	options.inputDatasetNameBackup = [];
	% Binary: 1 = convert file movie to double, 0 = keep original format.
	options.convertToDouble = 0;
	% Str: 'single','double'
	options.loadSpecificImgClass = [];
	% Binary: 1 = read frame by frame to save memory, 0 = read continuous chunk.
	options.forcePerFrameRead = 0;
	% Binary: 1 = waitbar/progress bar is shown, 0 = no progress shown.
	options.waitbarOn = 1;
	% Binary: 1 = just return the movie dimensions, do not load the movie.
	options.getMovieDims = 0;
	% Binary: 1 = treat movies in list as continuous with regards to frames to extract.
	options.treatMoviesAsContinuous = 0;
	% Binary: 1 = whether to display info on command line.
	options.displayInfo = 1;
	% Binary: Whether to display diagnostic information
	options.displayDiagnosticInfo = 0;
	% Binary: 1 = display diagnostic information, 0 = do not display diagnostic information.
	options.displayWarnings = 1;
	% Matrix: Pre-specify the size, if need to get around memory re-allocation issues
	options.presetMovieSize = [];
	% Binary: 1 = avoid pre-allocating if single large matrix, saves memory. 0 = pre-allocate matrix.
	options.largeMovieLoad = 0;
	% Int: [numParts framesPerPart] number of equal parts to load the movie in
	options.loadMovieInEqualParts = [];
	% Binary: 1 = only check information for 1st file then populate the rest with identical information, useful for folders with thousands of TIF or other images
	options.onlyCheckFirstFileInfo = 0;
	% Binary: 1 = h5info, 0 = hdf5info. DO NOT rely on this, will be deprecated/eliminated soon.
	options.useH5info = 1;
	% Int: [] = do nothing, 1-3 indicates R,G,B channels to take from multicolor RGB AVI
	options.rgbChannel = [];
	% Int: Bio-Formats series number to load.
	options.bfSeriesNo = 1;
	% Int: Bio-Formats channel number to load.
	options.bfChannelNo = 1;
	% Int: Bio-Formats z dimension to load.
	options.bfZdimNo = 1;
	% Cell array: Store file information, e.g. make TIFF reading faster.
	options.fileInfo = {};
	% get options
	options = ciapkg.io.getOptions(options,varargin);
	% unpack options into current workspace
	% fn=fieldnames(options);
	% for i=1:length(fn)
	%     eval([fn{i} '=options.' fn{i} ';']);
	% end

	startTime = tic;

    % Ensure all output arguments set
    outputMovie = NaN;
    movieDims = NaN;
    nPixels = NaN;
    nFrames = NaN;

	if options.displayInfo==1
		display(repmat('#',1,3))
	end

	% ========================
	% Create MAT-file object and variable
	if ~isempty(options.matfile)
		save(options.matfile,'outputMovie','-v7.3');
		matObj = matfile(options.matfile,'Writable',true);

		% There is no need to pre-allocate the MAT-file, skip.
		options.largeMovieLoad = 1;
	end

	% ========================
	% Allow usr to input just a string if a single movie
	if ischar(movieList)
		movieList = {movieList};
    end
    % Setup file info.
    if isempty(options.fileInfo)
        options.fileInfo = cell([1 length(movieList)]);
    end

	% ========================
	% modify frameList if loading equal parts
	if ~isempty(options.loadMovieInEqualParts)
		fprintf('Loading %d equal parts of %d frames each\n',options.loadMovieInEqualParts(1),options.loadMovieInEqualParts(2))
		options.frameList = subfxnLoadEqualParts(movieList,options);
	end

	% Remove any frames that are zero or negative, not valid.
	if ~isempty(options.frameList)
        if any(options.frameList<1)
            subfxnDisplay(['Removing invalid frames from user input frame list (negative or zero).'],options);
            options.frameList(options.frameList<1) = [];
        end
	end

	% ========================
	% remove unsupported files
	movieNo = 1;
	movieTypeList = cell([1 length(movieList)]);
	for iMovie = 1:length(movieList)
		thisMoviePath = movieList{iMovie};
		[options.movieType, supported] = getMovieFileType(thisMoviePath);
		movieTypeList{iMovie} = options.movieType;
		if supported==0
			subfxnDisplay(['removing unsupported file from list: ' thisMoviePath],options);
		else
			tmpMovieList{movieNo} = movieList{iMovie};
			movieNo = movieNo + 1;
		end
	end
	% if tmp doesn't exist, means no input files are valid, return
	if exist('tmpMovieList','var')
		movieList = tmpMovieList;
	else
		if options.displayInfo==1
			toc(startTime);
			display(repmat('#',1,3))
		end
		return;
	end
	numMovies = length(movieList);

	% Test that Inscopix MATLAB API ISX package installed
	if any(strcmp(movieTypeList,'isxd'))==1
		inputFilePathCheck = movieList{find(strcmp(movieTypeList,'isxd'),1,'first')};
		try
			inputMovieIsx = isx.Movie.read(inputFilePathCheck);
		catch
			ciapkg.inscopix.loadIDPS();
		end
	end

	% ========================
	% pre-read each file to allow pre-allocation of output file
	reverseStr = '';
	for iMovie=1:numMovies
		thisMoviePath = movieList{iMovie};
		if options.onlyCheckFirstFileInfo==1&&iMovie>1
			fprintf('Adding movie #1 info to movie info for %d\\%d: %s\n',iMovie,numMovies,thisMoviePath);
			dims.x(iMovie) = dims.x(1);
			dims.y(iMovie) = dims.y(1);
			dims.z(iMovie) = dims.z(1);
			dims.one(iMovie) = dims.one(1);
			dims.two(iMovie) = dims.two(1);
			dims.three(iMovie) = dims.three(1);
			continue
		end
		if options.displayInfo==1
			fprintf('Getting movie info for %d\\%d: %s\n',iMovie,numMovies,thisMoviePath);
		end
		[options.movieType, supported] = getMovieFileType(thisMoviePath);
		if supported==0

		end
		switch options.movieType
			case 'tiff'
				if options.displayWarnings==0
					warning off
				end
				warning off
				tiffHandle = Tiff(thisMoviePath, 'r+');
				warning on
				tmpFrame = tiffHandle.read();
				xyDims = size(tmpFrame);
                options.fileInfo{iMovie} = imfinfo(thisMoviePath,'tif');
                % nTiles = numberOfTiles(tiffHandle);
                nTiles = size(options.fileInfo{iMovie},1);;
				if options.displayWarnings==0
					warning on
				end

				% dims.class{iMovie} = class(tmpFrame);
				dims.x(iMovie) = xyDims(1);
				dims.y(iMovie) = xyDims(2);
				% dims.z(iMovie) = size(imfinfo(thisMoviePath),1);
				dims.z(iMovie) = nTiles;
				dims.one(iMovie) = xyDims(1);
				dims.two(iMovie) = xyDims(2);
				% dims.three(iMovie) = size(imfinfo(thisMoviePath),1);
                dims.three(iMovie) = nTiles;

				if dims.z(iMovie)==1
					% fileInfo = imfinfo(thisMoviePath,'tif');
                    fileInfo = options.fileInfo{iMovie};
					try
						numFramesStr = regexp(fileInfo.ImageDescription, 'images=(\d*)', 'tokens');
						nFrames = str2double(numFramesStr{1}{1});
					catch
						% Try to grab using TIFF library
						try
							nFrames = tiffHandle.numberOfTiles;
						catch
							nFrames = 1;
						end
					end
					dims.z(iMovie) = nFrames;
					dims.three(iMovie) = nFrames;
				end
				tiffHandle.close(); clear tiffHandle
			case 'hdf5'

				% Check if NWB file and alter input dataset name to default NWB if inputDatasetName does not point to a valid NWB dataset.
				[~,~,extTmp] = fileparts(thisMoviePath);
				if strcmp(extTmp,'.nwb')
					try
						h5info(thisMoviePath,options.inputDatasetName);
					catch
						for zCheck = 1:length(options.defaultNwbDatasetName)
							try
								options.inputDatasetName = options.defaultNwbDatasetName{zCheck};
								h5info(thisMoviePath,options.inputDatasetName);
							catch
								fprintf('Incorrect NWB dataset name: %s\n',options.inputDatasetName)
							end
						end
					end
				end
				clear extTmp zCheck;

				if options.useH5info==1
					hinfo = h5info(thisMoviePath);
				else
					hinfo = hdf5info(thisMoviePath);
				end
				[hReadInfo, thisDatasetName, datasetDims] = getHdf5Info();
				if options.displayDiagnosticInfo==1
					display(hReadInfo)
					hReadInfo.Name
				end
				hReadInfo.Dims = datasetDims;
				dims.x(iMovie) = hReadInfo.Dims(1);
				dims.y(iMovie) = hReadInfo.Dims(2);
				dims.one(iMovie) = hReadInfo.Dims(1);
				dims.two(iMovie) = hReadInfo.Dims(2);
				% Check 3rd dimension exists
				if length(hReadInfo.Dims)>=3
					dims.z(iMovie) = hReadInfo.Dims(3);
					dims.three(iMovie) = hReadInfo.Dims(3);
				else
					dims.z(iMovie) = 0;
					dims.three(iMovie) = 0;
				end

				if dims.z(iMovie)
					offsetTmp = [0 0 1];
					blockTmp = [dims.x(iMovie) dims.y(iMovie) 1];
				else
					offsetTmp = [0 0];
					blockTmp = [dims.x(iMovie) dims.y(iMovie)];
				end
				if ischar(options.inputDatasetName)
					tmpDataset = options.inputDatasetName;
				else
					tmpDataset = thisDatasetName;
				end
				tmpFrame = readHDF5Subset(thisMoviePath,offsetTmp,blockTmp,'datasetName',tmpDataset,'displayInfo',options.displayInfo);
			case 'avi'
				xyloObj = VideoReader(thisMoviePath);
				dims.x(iMovie) = xyloObj.Height;
				dims.y(iMovie) = xyloObj.Width;
				dims.z(iMovie) = xyloObj.NumberOfFrames;
				dims.one(iMovie) = xyloObj.Height;
				dims.two(iMovie) = xyloObj.Width;
				dims.three(iMovie) = xyloObj.NumberOfFrames;
				tmpFrame = read(xyloObj, 1, 'native');
				tmpFrame = tmpFrame.cdata;
				% tmpFrame = readFrame(xyloObj);
			case 'isxd'
				inputMovieIsx = isx.Movie.read(thisMoviePath);
				nFrames = inputMovieIsx.timing.num_samples;
				xyDims = inputMovieIsx.spacing.num_pixels;
				dims.x(iMovie) = xyDims(1);
				dims.y(iMovie) = xyDims(2);
				dims.z(iMovie) = nFrames;
				dims.one(iMovie) = xyDims(1);
				dims.two(iMovie) = xyDims(2);
				dims.three(iMovie) = nFrames;
				tmpFrame = inputMovieIsx.get_frame_data(0);
			case 'bioformats'
				bfreaderTmp = bfGetReader(thisMoviePath);
				bfreaderTmp.setSeries(options.bfSeriesNo);

				omeMeta = bfreaderTmp.getMetadataStore();
				stackSizeX = omeMeta.getPixelsSizeX(options.bfSeriesNo).getValue(); % image width, pixels
				stackSizeY = omeMeta.getPixelsSizeY(options.bfSeriesNo).getValue(); % image height, pixels
				stackSizeZ = omeMeta.getPixelsSizeZ(options.bfSeriesNo).getValue();
				% Get time points (frames) for this series
				nFrames = bfreaderTmp.getSizeT;

				xyDims = [stackSizeY stackSizeX];
				dims.x(iMovie) = xyDims(1);
				dims.y(iMovie) = xyDims(2);
				dims.z(iMovie) = nFrames;
				dims.one(iMovie) = xyDims(1);
				dims.two(iMovie) = xyDims(2);
				dims.three(iMovie) = nFrames;

				iPlane = bfreaderTmp.getIndex(0, options.bfChannelNo-1, 0)+1;
				tmpFrame = bfGetPlane(bfreaderTmp, iPlane);
				nChannels = omeMeta.getChannelCount(options.bfSeriesNo);
		end
		if isempty(options.loadSpecificImgClass)
			imgClass = class(tmpFrame);
		else
			imgClass = options.loadSpecificImgClass;
		end
		% change dims.z if user specifies a list of frames
		if (~isempty(options.frameList)|options.frameList>dims.z(iMovie))&options.treatMoviesAsContinuous==0
			% Disallow frames that are longer than the length of the movie
			frameListTmp = options.frameList;
			if any(frameListTmp>dims.three(iMovie))
				rmIDx = frameListTmp>dims.three(iMovie);
				if options.displayInfo==1
					fprintf('Removing %d frames outside movie length.\n',sum(rmIDx));
				end
				frameListTmp(rmIDx) = [];
			else
			end
			dims.z(iMovie) = length(frameListTmp);
		end
		if options.displayInfo==1
			reverseStr = cmdWaitbar(iMovie,numMovies,reverseStr,'inputStr','checking movies','waitbarOn',options.waitbarOn,'displayEvery',10);
		end
	end
	if options.getMovieDims==1
		outputMovie = dims;
		if options.displayInfo==1
			toc(startTime);
			display(repmat('#',1,3))
		end
		return;
	end
	% dims
	xDimMax = max(dims.x);
	yDimMax = max(dims.y);
	switch options.treatMoviesAsContinuous
		case 0
			zDimLength = sum(dims.z);
		case 1
			if isempty(options.frameList)
				zDimLength = sum(dims.z);
			else
				frameListTmp = options.frameList;
				zDimLength = length(frameListTmp);
				if any(zDimLength>sum(dims.three))
					rmIDx = frameListTmp>sum(dims.three);
					if options.displayInfo==1
						fprintf('Removing %d frames outside movie length.\n',sum(rmIDx));
					end
					frameListTmp(rmIDx) = [];
					zDimLength = length(frameListTmp);
				end
			end
		otherwise
			% body
	end
	% pre-allocated output structure, convert to input movie datatype
	% if strcmp(imgClass,'single')|strcmp(imgClass,'double')
	% 	if isempty(options.loadSpecificImgClass)
	% 		outputMovie = nan([xDimMax yDimMax zDimLength],imgClass);
	% 	else
	% 		display('pre-allocating single matrix...')
	% 		outputMovie = ones([xDimMax yDimMax zDimLength],imgClass);
	% 		% j = whos('outputMovie');j.bytes=j.bytes*9.53674e-7;display(['movie size: ' num2str(j.bytes) 'Mb | ' num2str(j.size) ' | ' j.class]);
	% 		% return;
	% 		outputMovie(:,:,:) = 0;
	% 	end
	% else
	% 	outputMovie = zeros([xDimMax yDimMax zDimLength],imgClass);
	% end

	% size(outputMovie)

	if options.treatMoviesAsContinuous==1&&~isempty(options.frameList)
		% totalZ = sum(dims.z);
		zdims = dims.z;
		frameList = options.frameList;
		zdimsCumsum = cumsum([0 zdims]);
		zdims = [1 zdims];
		for i=1:(length(zdims)-1)
			g{i} = frameList>zdimsCumsum(i)&frameList<=zdimsCumsum(i+1);
			globalFrame{i} = frameList(g{i}) - zdimsCumsum(i);
			dims.z(i) = length(globalFrame{i});
		end
		disp([cellfun(@max,globalFrame,'UniformOutput',false); cellfun(@min,globalFrame,'UniformOutput',false)])
		% pause
	else
		globalFrame = [];
	end

	% reshape movie if not including larger movies
	removeIdx = [];
	numList = 1:numMovies;
	for iMovie=numList
		if isempty(globalFrame)
			thisFrameList = options.frameList;
		else
			thisFrameList = globalFrame{iMovie};
			if isempty(thisFrameList)
				subfxnDisplay(['no global frames:' num2str(iMovie) '/' num2str(numMovies) ': ' thisMoviePath],options);
				removeIdx(end+1) = iMovie;
			end
		end
	end

	subfxnDisplay('-------',options);
	keepIdx = setdiff(numList,removeIdx);
	xDimMax = nanmax(dims.x(keepIdx));
	yDimMax = nanmax(dims.y(keepIdx));

	% pre-allocated output structure, convert to input movie datatype
	if options.largeMovieLoad==1
	else
		if strcmp(imgClass,'single')||strcmp(imgClass,'double')
			if isempty(options.loadSpecificImgClass)
				preallocSize = [xDimMax yDimMax zDimLength];
				subfxnDisplay(['pre-allocating ' imgClass ' NaN matrix: ' num2str(preallocSize)],options);
				outputMovie = NaN(preallocSize,imgClass);
			else
				preallocSize = [xDimMax yDimMax zDimLength];
				% subfxnDisplay('pre-allocating single ones matrix...',options);
				subfxnDisplay(['pre-allocating ' imgClass ' ones matrix: ' num2str(preallocSize)],options);
				outputMovie = ones(preallocSize,imgClass);
				% j = whos('outputMovie');j.bytes=j.bytes*9.53674e-7;display(['movie size: ' num2str(j.bytes) 'Mb | ' num2str(j.size) ' | ' j.class]);
				% return;
				outputMovie(:,:,:) = 0;
			end
		else
			preallocSize = [xDimMax yDimMax zDimLength];
			% subfxnDisplay('pre-allocating single zeros matrix...',options);
			subfxnDisplay(['pre-allocating ' imgClass ' zeros matrix: ' num2str(preallocSize)],options);
			outputMovie = zeros(preallocSize,imgClass);
		end
	end
	subfxnDisplay('-------',options);
	% ========================
	for iMovie=1:numMovies
		thisMoviePath = movieList{iMovie};

		[options.movieType] = getMovieFileType(thisMoviePath);

		if isempty(globalFrame)
			thisFrameList = options.frameList;
		else
			thisFrameList = globalFrame{iMovie};
			if isempty(thisFrameList)
				subfxnDisplay(['no global frames:' num2str(iMovie) '/' num2str(numMovies) ': ' thisMoviePath],options);
				continue
			end
		end

		% Remove any frames that are outside the movie length.
		if any(thisFrameList>dims.three(iMovie))
			rmIDx2 = thisFrameList>dims.three(iMovie);
			if options.displayInfo==1
				fprintf('Removing %d frames outside movie length.\n',sum(rmIDx2));
			end
			thisFrameList(rmIDx2) = [];
		end

		if options.displayInfo==1
			subfxnDisplay(['loading ' num2str(iMovie) '/' num2str(numMovies) ': ' thisMoviePath],options);
		end
		% depending on movie type, load differently
		switch options.movieType
			case 'tiff'
				% Pre-load the temporary image to reduce overhead and boost performance when loading many individual TIF images
				if iMovie==1&&options.onlyCheckFirstFileInfo==1
					thisMoviePath = movieList{iMovie};
					tiffHandle = Tiff(thisMoviePath, 'r');
					tmpFramePerma = tiffHandle.read();
					% fileInfoH = imfinfo(thisMoviePath,'tif');
                    fileInfoH = options.fileInfo{iMovie};
					displayInfoH = 1;
					NumberframeH = dims.z(iMovie);
				elseif options.onlyCheckFirstFileInfo==1&&iMovie>1
					displayInfoH = 0;
					NumberframeH = dims.z(iMovie);
                    fileInfoH = options.fileInfo{iMovie};
				else
					% For all other cases (e.g. TIF stacks) don't alter
					tmpFramePerma = [];
					displayInfoH = 1;
					Numberframe = [];
					NumberframeH = [];
					fileInfoH = options.fileInfo{iMovie};
				end

				if options.displayInfo==0
					displayInfoH = 0;
				end

				if numMovies==1
					if isempty(thisFrameList)
						outputMovie = load_tif_movie(thisMoviePath,1,'displayInfo',options.displayInfo,'fileInfo',fileInfoH);
						% outputMovie = outputMovie.Movie;
					else
						outputMovie = load_tif_movie(thisMoviePath,1,'frameList',thisFrameList,'displayInfo',options.displayInfo,'fileInfo',fileInfoH);
					end

					if isempty(options.matfile)
						outputMovie = outputMovie.Movie;
					else
						matObj.outputMovie = outputMovie.Movie;
					end
				else
					if isempty(thisFrameList)
						tmpMovie = load_tif_movie(thisMoviePath,1,'tmpImage',tmpFramePerma,'displayInfo',displayInfoH,'Numberframe',NumberframeH,'fileInfo',fileInfoH);
						% tmpMovie = tmpMovie.Movie;
					else
						tmpMovie = load_tif_movie(thisMoviePath,1,'frameList',thisFrameList,'tmpImage',tmpFramePerma,'displayInfo',displayInfoH,'Numberframe',NumberframeH,'fileInfo',fileInfoH);
					end

					if isempty(options.matfile)
						tmpMovie = tmpMovie.Movie;
					else
						if iMovie==1
							if dims.z(iMovie)==0
								matObj.outputMovie(1:dims.x(iMovie),1:dims.y(iMovie),1) = tmpMovie.Movie;
							else
								matObj.outputMovie(1:dims.x(iMovie),1:dims.y(iMovie),1:dims.z(iMovie)) = tmpMovie.Movie;
							end
						else
							% assume 3D movies with [x y frames] as dimensions
							zOffset = sum(dims.z(1:iMovie-1));
							matObj.outputMovie(1:dims.x(iMovie),1:dims.y(iMovie),(zOffset+1):(zOffset+dims.z(iMovie))) = tmpMovie.Movie;
						end
					end
				end
			% ========================
			case 'hdf5'
				if isempty(thisFrameList)&&options.forcePerFrameRead==0
					if options.useH5info==1
						hinfo = h5info(thisMoviePath);
					else
						hinfo = hdf5info(thisMoviePath);
					end
					% hReadInfo = hinfo.GroupHierarchy.Datasets(1);
					% datasetNames = {hinfo.GroupHierarchy.Datasets.Name};
					% thisDatasetName = strmatch(inputDatasetName,datasetNames);
					% hReadInfo = hinfo.GroupHierarchy.Datasets(thisDatasetName);
					hReadInfo = getHdf5Info();
					% read in the file
					% hReadInfo.Attributes
					if options.largeMovieLoad==1&&numMovies==1
						if options.useH5info==1
							outputMovie = h5read(thisMoviePath,options.inputDatasetName);
						else
							outputMovie = hdf5read(hReadInfo);
						end
					else
						if options.useH5info==1
							tmpMovie = h5read(thisMoviePath,options.inputDatasetName);
						else
							tmpMovie = hdf5read(hReadInfo);
						end
						if isempty(options.loadSpecificImgClass)
						else
							tmpMovie = cast(tmpMovie,imgClass);
						end
					end
				else
					% xxxx = 1;
					if sum(nanmin(diff(thisFrameList)==1))==1&&options.forcePerFrameRead==0
						% if contiguous segment of HDF5 file, read that in as one block to save time if user specifies as such
						inputFilePath = thisMoviePath;
						framesToGrab = thisFrameList;
						if options.useH5info==1
							hinfo = h5info(inputFilePath);
						else
							hinfo = hdf5info(inputFilePath);
						end
						% hReadInfo = hinfo.GroupHierarchy.Datasets(1);
						[hReadInfo, thisDatasetName, datasetDims] = getHdf5Info();
						hReadInfo.Dims = datasetDims;
						xDim = hReadInfo.Dims(1);
						yDim = hReadInfo.Dims(2);

						subfxnDisplay(['loading movie as contiguous chunk: ' num2str([0 0 framesToGrab(1)-1]) ' | ' num2str([xDim yDim length(framesToGrab)])],options);
						% tmpMovie = readHDF5Subset(inputFilePath,[0 0 framesToGrab(1)-1],[xDim yDim length(framesToGrab)],'datasetName',options.inputDatasetName);
						% size(tmpMovie)
						% size(outputMovie)
						if ischar(options.inputDatasetName)
							tmpMovie = readHDF5Subset(inputFilePath,[0 0 framesToGrab(1)-1],[xDim yDim length(framesToGrab)],'datasetName',options.inputDatasetName,'displayInfo',options.displayInfo);
						else
							tmpMovie = readHDF5Subset(inputFilePath,[0 0 framesToGrab(1)-1],[xDim yDim length(framesToGrab)],'datasetName',thisDatasetName,'displayInfo',options.displayInfo);
						end
					else
						subfxnDisplay('Read frame-by-frame',options)
						% read frame-by-frame to save space
						inputFilePath = thisMoviePath;
						if options.useH5info==1
							hinfo = h5info(inputFilePath);
						else
							hinfo = hdf5info(inputFilePath);
						end
						% hReadInfo = hinfo.GroupHierarchy.Datasets(1);
						[hReadInfo, thisDatasetName, datasetDims] = getHdf5Info();
						hReadInfo.Dims = datasetDims;
						xDim = hReadInfo.Dims(1);
						yDim = hReadInfo.Dims(2);
						% tmpMovie = readHDF5Subset(inputFilePath,[0 0 thisFrameList(1)],[xDim yDim length(thisFrameList)],'datasetName',options.inputDatasetName);
						framesToGrab = thisFrameList;
						if isempty(thisFrameList)&&options.forcePerFrameRead==1
							framesToGrab = 1:dims.z(iMovie);
						end
						nFrames = length(framesToGrab);
						% reverseStr = '';

						for iframe = 1:nFrames
							readFrame = framesToGrab(iframe);
							offsetT{iframe} = [0 0 readFrame-1];
							blockT{iframe} = [xDim yDim 1];
						end
						if ischar(options.inputDatasetName)
							thisFrame = readHDF5Subset(inputFilePath,offsetT,blockT,'datasetName',options.inputDatasetName,'displayInfo',0);
						else
							thisFrame = readHDF5Subset(inputFilePath,offsetT,blockT,'datasetName',thisDatasetName,'displayInfo',0);
						end
						if isempty(options.loadSpecificImgClass)
							% tmpMovie(:,:,iframe) = thisFrame;
							outputMovie(1:dims.x(iMovie),1:dims.y(iMovie),1:nFrames) = thisFrame;
						else
							% assume 3D movies with [x y frames] as dimensions
							if(iMovie==1)
								outputMovie(1:dims.x(iMovie),1:dims.y(iMovie),1:nFrames) = cast(thisFrame,imgClass);
							else
								zOffset = sum(dims.z(1:iMovie-1));
								outputMovie(1:dims.x(iMovie),1:dims.y(iMovie),(zOffset+1:nFrames)) = cast(thisFrame,imgClass);
							end
						end
						% if options.displayInfo==1
						% 	reverseStr = cmdWaitbar(iframe,nFrames,reverseStr,'inputStr','loading hdf5','waitbarOn',options.waitbarOn,'displayEvery',50);
						% end

						% for iframe = 1:nFrames
						% 	readFrame = framesToGrab(iframe);
						% 	if ischar(options.inputDatasetName)
						% 		thisFrame = readHDF5Subset(inputFilePath,[0 0 readFrame-1],[xDim yDim 1],'datasetName',options.inputDatasetName,'displayInfo',0);
						% 	else
						% 		thisFrame = readHDF5Subset(inputFilePath,[0 0 readFrame-1],[xDim yDim 1],'datasetName',thisDatasetName,'displayInfo',0);
						% 	end
						% 	if isempty(options.loadSpecificImgClass)
						% 		% tmpMovie(:,:,iframe) = thisFrame;
						% 		outputMovie(1:dims.x(iMovie),1:dims.y(iMovie),iframe) = thisFrame;
						% 	else
						%     	% assume 3D movies with [x y frames] as dimensions
						% 	    if(iMovie==1)
						% 			outputMovie(1:dims.x(iMovie),1:dims.y(iMovie),iframe) = cast(thisFrame,imgClass);
						% 	    else
						% 	    	zOffset = sum(dims.z(1:iMovie-1));
						% 	    	outputMovie(1:dims.x(iMovie),1:dims.y(iMovie),(zOffset+iframe)) = cast(thisFrame,imgClass);
						% 	    end
						% 	end
						% 	if options.displayInfo==1
						% 		reverseStr = cmdWaitbar(iframe,nFrames,reverseStr,'inputStr','loading hdf5','waitbarOn',options.waitbarOn,'displayEvery',50);
						% 	end
						% end
					end
				end
			% ========================
			case 'avi'
				xyloObj = VideoReader(thisMoviePath);

				if isempty(thisFrameList)
					nFrames = xyloObj.NumberOfFrames;
					framesToGrab = 1:nFrames;
				else
					nFrames = length(thisFrameList);
					framesToGrab = thisFrameList;
				end
				vidHeight = xyloObj.Height;
				vidWidth = xyloObj.Width;

				% Preallocate movie structure.
				tmpMovie = zeros(vidHeight, vidWidth, nFrames, 'uint8');

				% Read one frame at a time.
				reverseStr = '';
				iframe = 1;
				nFrames = length(framesToGrab);
				for iframe = 1:nFrames
					readFrame = framesToGrab(iframe);
					tmpAviFrame = read(xyloObj, readFrame);
					% check if frame is RGB or grayscale, if RGB only take one channel (since they will be identical for RGB grayscale)
					if size(tmpAviFrame,3)==3&isempty(options.rgbChannel)
						tmpAviFrame = squeeze(tmpAviFrame(:,:,1));
					elseif ~isempty(options.rgbChannel)
						tmpAviFrame = squeeze(tmpAviFrame(:,:,options.rgbChannel));
					end
					tmpMovie(:,:,iframe) = tmpAviFrame;
					% reduce waitbar access
					if options.displayInfo==1
						reverseStr = cmdWaitbar(iframe,nFrames,reverseStr,'inputStr','loading avi','waitbarOn',options.waitbarOn,'displayEvery',50);
					end
					iframe = iframe + 1;
				end
			% ========================
			case 'isxd'
				% Setup movie class
				inputMovieIsx = isx.Movie.read(thisMoviePath);
				nFramesHere = inputMovieIsx.timing.num_samples;
				xyDims = inputMovieIsx.spacing.num_pixels;

				if isempty(thisFrameList)
					nFrames = nFramesHere;
					framesToGrab = 1:nFrames;
				else
					nFrames = length(thisFrameList);
					framesToGrab = thisFrameList;
				end
				vidHeight = xyDims(1);
				vidWidth = xyDims(2);

				% Preallocate movie structure.
				tmpMovie = zeros(vidHeight, vidWidth, nFrames, imgClass);

				% Read one frame at a time.
				reverseStr = '';
				iframe = 1;
				nFrames = length(framesToGrab);
				for iframe = 1:nFrames
					readFrame = framesToGrab(iframe);
					tmpAviFrame = inputMovieIsx.get_frame_data(readFrame-1);
					% tmpAviFrame = read(xyloObj, readFrame);
					% check if frame is RGB or grayscale, if RGB only take one channel (since they will be identical for RGB grayscale)
					% if size(tmpAviFrame,3)==3
					% 	tmpAviFrame = squeeze(tmpAviFrame(:,:,1));
					% end
					tmpMovie(:,:,iframe) = tmpAviFrame;
					% reduce waitbar access
					if options.displayInfo==1
						reverseStr = cmdWaitbar(iframe,nFrames,reverseStr,'inputStr','loading ISXD','waitbarOn',options.waitbarOn,'displayEvery',50);
					end
					iframe = iframe + 1;
				end
			% ========================
			case 'bioformats'
				% Setup movie class
				bfreaderTmp = bfGetReader(thisMoviePath);
				bfreaderTmp.setSeries(options.bfSeriesNo);

				omeMeta = bfreaderTmp.getMetadataStore();
				stackSizeX = omeMeta.getPixelsSizeX(options.bfSeriesNo).getValue(); % image width, pixels
				stackSizeY = omeMeta.getPixelsSizeY(options.bfSeriesNo).getValue(); % image height, pixels
				stackSizeZ = omeMeta.getPixelsSizeZ(options.bfSeriesNo).getValue();
				nChannels = omeMeta.getChannelCount(options.bfSeriesNo);

				% Get the number of time points (frames).
				nFramesHere = bfreaderTmp.getSizeT;

				xyDims = [stackSizeX stackSizeY];

				if isempty(thisFrameList)
					nFrames = nFramesHere;
					framesToGrab = 1:nFrames;
				else
					nFrames = length(thisFrameList);
					framesToGrab = thisFrameList;
				end
				vidHeight = xyDims(2);
				vidWidth = xyDims(1);

				% Preallocate movie structure.
				if numMovies==1
					outputMovie = zeros(vidHeight, vidWidth, nFrames, imgClass);
				else
					tmpMovie = zeros(vidHeight, vidWidth, nFrames, imgClass);
				end

				% Read one frame at a time.
				reverseStr = '';
				iframe = 1;
				nFrames = length(framesToGrab);

				zPlane = 0;
				iZ = 1;
				dispEvery = round(nFrames/20);
				% Adjust for zero-based indexing
				framesToGrab = framesToGrab-1;

				% figure;
				reverseStr = '';
				for t = framesToGrab
					iPlane = bfreaderTmp.getIndex(zPlane, options.bfChannelNo-1, t)+1;
					tmpFrame = bfGetPlane(bfreaderTmp, iPlane);
					% figure;
					% imagesc(tmpFrame);
					if numMovies==1
						outputMovie(:,:,iZ) = tmpFrame;
					else
						tmpMovie(:,:,iZ) = tmpFrame;
					end
					iZ = iZ+1;

					if options.displayInfo==1
						reverseStr = cmdWaitbar(iZ,nFrames,reverseStr,'inputStr','Loading bio-formats file: ','waitbarOn',options.waitbarOn,'displayEvery',dispEvery);
					end
					% pause(0.01)
				end
				if numMovies==1
					clear tmpMovie
				end
				% ciapkg.api.playMovie(tmpMovie);
				% size(tmpMovie)

				% continue;
				extraBioformatsFlag = 0;
				if extraBioformatsFlag==1
					% Read in movie data
					tmpMovie = bfopen(thisMoviePath);

					% bfopen returns an n-by-4 cell array, where n is the number of series in the dataset. If s is the series index between 1 and n:
					% The data{s, 1} element is an m-by-2 cell array, where m is the number of planes in the s-th series. If t is the plane index between 1 and m:
					% The data{s, 1}{t, 1} element contains the pixel data for the t-th plane in the s-th series.
					% The data{s, 1}{t, 2} element contains the label for the t-th plane in the s-th series.
					% The data{s, 2} element contains original metadata key/value pairs that apply to the s-th series.
					% The data{s, 3} element contains color lookup tables for each plane in the s-th series.
					% The data{s, 4} element contains a standardized OME metadata structure, which is the same regardless of the input file format, and contains common metadata values such as physical pixel sizes - see OME metadata below for examples.

					% Frame information
					frameInfo = tmpMovie{options.bfSeriesNo, 1}(:,2);

					% Grab just the movie frames and convert from cell to matrix.
					tmpMovie = tmpMovie{options.bfSeriesNo, 1}(:,1);
					tmpMovie = cat(3,tmpMovie{:});

					% Only keep single channel if more than 1 channel in an image.
					if nChannels>1
						try
							chanKeepIdx = cell2mat(cellfun(@(x) str2num(cell2mat(regexp(x,'(?<=C\?=|C=)\d+(?=/)','match'))),frameInfo,'UniformOutput',false));
							chanKeepIdx = chanKeepIdx==options.bfChannelNo;
							tmpMovie = tmpMovie(:,:,chanKeepIdx);
						catch err
							disp(repmat('@',1,7))
							disp(getReport(err,'extended','hyperlinks','on'));
							disp(repmat('@',1,7))
						end
					end
				end
			% ========================
			otherwise
				% let's just not deal with this for now
				return;
		end
		if exist('tmpMovie','var')
			if iMovie==1
				if dims.z(iMovie)==0
					outputMovie(1:dims.x(iMovie),1:dims.y(iMovie),1) = tmpMovie;
				else
					outputMovie(1:dims.x(iMovie),1:dims.y(iMovie),1:dims.z(iMovie)) = tmpMovie;
				end
				% outputMovie(:,:,:) = tmpMovie;
			else
				% assume 3D movies with [x y frames] as dimensions
				zOffset = sum(dims.z(1:iMovie-1));
				outputMovie(1:dims.x(iMovie),1:dims.y(iMovie),(zOffset+1):(zOffset+dims.z(iMovie))) = tmpMovie;
				% outputMovie(:,:,end+1:end+size(tmpMovie,3)) = tmpMovie;
			end
			clear tmpMovie;
		else

		end
	end

	% hinfo = hdf5info('A:\shared\concatenated_2013_07_05_p62_m728_MAG1.h5');
	% DFOF = hdf5read(hinfo.GroupHierarchy.Datasets(1));
	% get size of movie
	% DFOFsize = size(DFOF.Movie);
	movieDims = size(outputMovie);
	nPixels = movieDims(1)*movieDims(2);
	if length(movieDims)==2
		nFrames = 1;
	else
		nFrames = movieDims(3);
	end
	if options.waitbarOn==1
		subfxnDisplay(['movie class: ' class(outputMovie)],options);
		subfxnDisplay(['movie size: ' num2str(size(outputMovie))],options);
		subfxnDisplay(['x-dims: ' num2str(dims.x)],options);
		subfxnDisplay(['y-dims: ' num2str(dims.y)],options);
		subfxnDisplay(['z-dims: ' num2str(dims.z)],options);
	end
	j = whos('outputMovie');j.bytes=j.bytes*9.53674e-7;
	subfxnDisplay(['movie size: ' num2str(j.bytes) 'Mb | ' num2str(j.size) ' | ' j.class],options);
	% display(dims);
	% Convert the movie to single
	% DFOF=single(DFOF);
	if options.convertToDouble==1
		subfxnDisplay('converting to double...',options);
		outputMovie=double(outputMovie);
	end

	if options.displayInfo==1
		toc(startTime);
		display(repmat('#',1,3))
	end

	function [hReadInfo, thisDatasetName, datasetDims] = getHdf5Info()
		if ischar(options.inputDatasetName)
			try
				if options.useH5info==1
					datasetNames = {hinfo.Datasets.Name};
					% Strip leading forward slash for h5info compatability
					thisDatasetName = strcmp(options.inputDatasetName(2:end),datasetNames);
					hReadInfo = hinfo.Datasets(thisDatasetName);
					if isempty(hReadInfo)
						hReadInfo = h5info(thisMoviePath,options.inputDatasetName);
						thisDatasetName = options.inputDatasetName;
					end
					datasetDims = hReadInfo.Dataspace.Size;
				else
					datasetNames = {hinfo.GroupHierarchy.Datasets.Name};
					thisDatasetName = strcmp(options.inputDatasetName,datasetNames);
					hReadInfo = hinfo.GroupHierarchy.Datasets(thisDatasetName);
					if isempty(hReadInfo)
						hReadInfo = h5info(thisMoviePath,options.inputDatasetName);
						datasetDims = hReadInfo.Dataspace.Size;
						thisDatasetName = options.inputDatasetName;
					else
						datasetDims = hReadInfo.Dims;
					end
				end
			catch err
				try
					if options.displayDiagnosticInfo==1
						disp(repmat('@',1,7))
						disp(getReport(err,'extended','hyperlinks','on'));
						disp(repmat('@',1,7))
						h5disp(thisMoviePath)
					elseif options.displayWarnings==1
						warning('HDF5 dataset name not found in hinfo.Datasets.Name. Trying another method to load HDF5 dataset.')
					end
				catch
				end
				try
					hReadInfo = h5info(thisMoviePath,options.inputDatasetName);
					datasetDims = hReadInfo.Dataspace.Size;
					thisDatasetName = options.inputDatasetName;
				catch err
					try
						if options.displayDiagnosticInfo==1
							disp(repmat('@',1,7))
							disp(getReport(err,'extended','hyperlinks','on'));
							disp(repmat('@',1,7))
						elseif options.displayWarnings==1
							warning('Could not find %s in %s.',options.inputDatasetName,thisMoviePath)
						end
					catch
					end
					try
						datasetNames = {hinfo.GroupHierarchy.Groups.Datasets.Name};
						thisDatasetName = strmatch(options.inputDatasetName,datasetNames);
						hReadInfo = hinfo.GroupHierarchy.Groups.Datasets(thisDatasetName);
					catch err
						try
							if options.displayDiagnosticInfo==1
								disp(repmat('@',1,7))
								disp(getReport(err,'extended','hyperlinks','on'));
								disp(repmat('@',1,7))
							elseif options.displayWarnings==1
								warning('HDF5 hinfo.GroupHierarchy.Groups.Datasets contains no dataset %s.',thisDatasetName)
							end
						catch
						end
						nGroups = length(hinfo.GroupHierarchy.Groups);
						datasetNames = {};
						for groupNo = 1:nGroups
							datasetNames{groupNo} = hinfo.GroupHierarchy.Groups(groupNo).Datasets.Name;
						end
						thisDatasetName = strmatch(options.inputDatasetName,datasetNames);
						thisGroupNo = strmatch(options.inputDatasetName,datasetNames);
						% hReadInfo = hinfo.GroupHierarchy.Groups(thisDatasetName).Datasets;
						% hinfo.GroupHierarchy.Groups(thisGroupNo).Datasets.Name
						thisDatasetNo = strmatch(options.inputDatasetName,{hinfo.GroupHierarchy.Groups(thisGroupNo).Datasets.Name});
						hReadInfo = hinfo.GroupHierarchy.Groups(thisGroupNo).Datasets(thisDatasetNo);
					end
				end
			end
		else
			hReadInfo = hinfo.GroupHierarchy.Datasets(options.inputDatasetName);
			thisDatasetName = hinfo.GroupHierarchy.Datasets(options.inputDatasetName).Name;
		end
	end
end
% function [movieType, supported] = getMovieFileType(thisMoviePath)
% 	% determine how to load movie, don't assume every movie in list is of the same type
% 	supported = 1;
% 	try
% 		[pathstr,name,ext] = fileparts(thisMoviePath);
% 	catch
% 		movieType = '';
% 		supported = 0;
% 		return;
% 	end
% 	% files are assumed to be named correctly (lying does no one any good)
% 	if any(strcmp(ext,{'.h5','.hdf5','.HDF5'}))
% 		movieType = 'hdf5';
% 	elseif strcmp(ext,'.nwb')
% 		movieType = 'hdf5';
% 	elseif any(strcmp(ext,{'.tif','.tiff'}))
% 		movieType = 'tiff';
% 	elseif strcmp(ext,'.avi')
% 		movieType = 'avi';
% 	elseif strcmp(ext,'.isxd') % Inscopix file format
% 		movieType = 'isxd';
% 	elseif strcmp(ext,'.ndpi') % Hamamatsu file format
% 		movieType = 'bioformats';
% 	elseif strcmp(ext,'.oir') % Olympus file format
% 		movieType = 'bioformats';
% 	elseif any(strcmp(ext,{'.czi','.lsm'})) % Zeiss file format
% 		movieType = 'bioformats';
% 	elseif endsWith(ext,'.sld') % SlideBook file format
% 		movieType = 'bioformats';
% 	else
% 		movieType = '';
% 		supported = 0;
% 	end
% end
function subfxnDisplay(str,options)
	if options.displayInfo==1
		disp(str)
	end
end

function frameListTmp = subfxnLoadEqualParts(movieList,options)
    import ciapkg.api.* % import CIAtah functions in ciapkg package API.

	movieDims = loadMovieList(movieList,'convertToDouble',options.convertToDouble,'frameList',[],'inputDatasetName',options.inputDatasetName,'treatMoviesAsContinuous',options.treatMoviesAsContinuous,'loadSpecificImgClass',options.loadSpecificImgClass,'getMovieDims',1);

	loadMovieInEqualParts = options.loadMovieInEqualParts(1);
	defaultNumFrames = options.loadMovieInEqualParts(2);
	tmpList = round(linspace(1,sum(movieDims.z)-defaultNumFrames,loadMovieInEqualParts));
	display(['tmpList' num2str(tmpList)])
	tmpList = bsxfun(@plus,tmpList,[1:defaultNumFrames]');

	frameListTmp = tmpList(:);
	frameListTmp(frameListTmp<1) = [];
	frameListTmp(frameListTmp>sum(movieDims.z)) = [];
	frameListTmp = unique(frameListTmp);

	% [primaryMovie] = loadMovieList(movieListTmp2,'convertToDouble',0,'frameList',frameListTmp(:),'treatMoviesAsContinuous',treatMoviesAsContinuous,'inputDatasetName',obj.inputDatasetName);
end

author: bahanonu

repo: ciatah

save_path: github-repos/MATLAB/bahanonu-ciatah


text:
function r8vec_sorted_unique_hist_test ( )

%*****************************************************************************80
%
%% R8VEC_SORTED_UNIQUE_HIST_TEST tests R8VEC_SORTED_UNIQUE_HIST.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 April 2009
%
%  Author:
%
%    John Burkardt
%
  n = 30;
  tol = 0.25;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'R8VEC_SORTED_UNIQUE_HIST_TEST\n' );
  fprintf ( 1, '  R8VEC_SORTED_UNIQUE_HIST makes a historgram of\n' );
  fprintf ( 1, '  the unique entries in a real vector.\n' );

  b = 0.0;
  c = n;
  seed = 123456789;

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Using random number seed %d\n', seed );

  [ a, seed ] = r8vec_uniform_ab ( n, b, c, seed );

  a(1:n) = round ( a(1:n) ) + 0.5;

  r8vec_print ( n, a, '  Unsorted array:' );

  a = r8vec_sort_bubble_a ( n, a );

  r8vec_print ( n, a, '  Ascending sorted array:' );

  [ unique_num, auniq, acount ] = r8vec_sorted_unique_hist ( n, a, tol );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  R8VEC_SORTED_UNIQUE_HIST counts %d unique entries.\n', ...
    unique_num );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Value  Multiplicity\n' );
  fprintf ( 1, '\n' );
  for i = 1 : unique_num
    fprintf ( 1, '  %6d  %12f  %6d\n', i, auniq(i), acount(i) );
  end

  return
end

author: johannesgerer

repo: jburkardt-m


text:
function I = mi_mixture_gd_vec(x, y, Ym)
% MI_MIXTURE_GD_VEC Vectorized MI calculation between multiple Gaussian variables
%         and a common discrete variable in bits from Gaussian mixture.
%   I = mi_mixture_gd_vec(x,y,Ym) returns the MI between the (possibly multidimensional)
%   Gaussian variables x and the discrete variable y.
%   size(x) = [Ntrl Nvec Ndim]
%   so each output I(i) = mi_mixture_gd(squeeze(x(:,i,:)), y, Ym);
%
%   y should contain integer values in the range [0 Ym-1] (inclusive).
%
%   biascorrect : true / false option (default true) which specifies whether
%   bias correction should be applied to the esimtated MI.
%   demeaned : false / true option (default false) which specifies whether the
%   input data already has zero mean (true if it has been copula-normalized)
%   See also: MI_MIXTURE_GD, MI_MODEL_GD_VEC

% ensure samples first axis for vectors
if isvector(x)
    x = x(:);
end
if ndims(x)>3
    error('mi_model_gd: input arrays should be 3d')
end
if isvector(y)
    y = y(:);
else
    error('mi_model_gd: only univariate discrete variable supported');
end

Ntrl = size(x,1);
Nvec = size(x,2);
Xdim = size(x,3);

if size(y,1) ~= Ntrl
    error('mi_model_gd: number of trials do not match');
end

I = zeros(Nvec,1);

% y = y-1;
% for vi=1:Nvec
%   I(vi) = mi_model_gd(squeeze(x(:,vi,:)),y,Ym,true,true);
% end
%
% return

% one-hot encoding of Y
Yhot = indexed2boolean(y);

% remove class means
[Xcen class_means] = removeclassmeans(x, Yhot);

% allocate memory for class-conditional entropies and covariances
Ntrl_y = sum(Yhot);
Hcond  = zeros(Nvec,Ym);
Cm     = zeros(Nvec,Xdim,Xdim,Ym);

for vi1=1:Xdim
  % all voxels for this dimension
  x1 = Xcen(:,:,vi1);
  for yi=1:Ym
    tmp = x1(Yhot(:,yi),:);
    Cm(:,vi1,vi1,yi) = sum(tmp.^2);
  end

  for vi2=(vi1+1):Xdim
    x2  = Xcen(:,:,vi2);
    for yi=1:Ym
      tmp = transpose(sum(x1(Yhot(:,yi),:).*x2(Yhot(:,yi),:)));
      Cm(:,vi1,vi2,yi) = tmp;
      Cm(:,vi2,vi1,yi) = tmp;
    end
  end
end

for yi=1:Ym
  Cm(:,:,:,yi) = Cm(:,:,:,yi) / (Ntrl_y(yi) - 1);
  Cm(:,:,:,yi) = vecchol(Cm(:,:,:,yi));
  for vi=1:Xdim
    Hcond(:,yi) = Hcond(:,yi)+log(Cm(:,vi,vi,yi));
  end
end
% class weights
w = Ntrl_y ./ Ntrl;
% normalise entropy properly
Hcond = Hcond + 0.5*Xdim*(log(2*pi)+1);

% mixture entropy via unscented transform
% See:
% Huber, Bailey, Durrant-Whyte and Hanebeck
% "On entropy approximation for Gaussian mixture random vectors"
% http://dx.doi.org/10.1109/MFI.2008.4648062
%
% Goldberger, Gordon, Greenspan
% "An efficient image similarity measure based on approximations of
% KL-divergence between two Gaussian mixtures"
% http://dx.doi.org/10.1109/ICCV.2003.1238387

D = Xdim;
Ds = sqrt(Xdim);
Hmix = zeros(Nvec,1);
chC = Cm;

m = reshape(class_means,[Nvec Xdim Ym]);
for yi=1:Ym
    % vector transpose
    Ps = Ds * permute(chC(:,:,:,yi), [1 3 2]);
    % unscented points for this class
    usc = cat(3,bsxfun(@plus,Ps,m(:,:,yi)), bsxfun(@minus,m(:,:,yi),Ps));

    % class log-likelihoods at unscented points
    log_lik = zeros(Ym,Nvec,2*Xdim);
    for mi=1:Ym
        % demean points
        dx = bsxfun(@minus,usc,m(:,:,mi));
        % gaussian likelihood
        log_lik(mi,:,:) = bsxfun(@minus,norm_innerv(dx, chC(:,:,:,mi)), Hcond(:,mi)) + 0.5*Xdim;
    end
    % log mixture likelihood for these unscented points
    logmixlik = maxstar(log_lik, w);
    % add to entropy estimate
    Hmix = Hmix + w(yi)*sum(logmixlik,2);
end
Hmix = -Hmix/(2*D);

% compute mutual information
I = Hmix - Hcond*w';

% convert to bits
I = I / log(2);

function [Xcen, class_means] = removeclassmeans(X, design)
[Ntrl, Nvec, Ndim] = size(X);
Xcen = X(:,:);
class_means = zeros(Nvec*Ndim,size(design,2));
for k = 1:size(design,2)
  sel = design(:,k);
  tmp = Xcen(sel,:);
  class_means(:,k) = mean(tmp,1);
  Xcen(sel,:) = bsxfun(@minus,tmp,class_means(:,k).');
end
Xcen = reshape(Xcen,[Ntrl Nvec Ndim]);

function Y = indexed2boolean(X)
uX = unique(X);
Y  = false(numel(X),numel(uX));
for k = 1:size(Y,2)
  Y(X==uX(k),k) = true;
end

function w = norm_innerv(x, chC)
% normalised innervations
Nvec = size(chC,1);
w = zeros(Nvec,size(x,3));
for vi=1:Nvec
  m = (squeeze(chC(vi,:,:))')\(squeeze(x(vi,:,:)));
  w(vi,:) = -0.5 *sum(m.*m,1);
end

author: fieldtrip

repo: fieldtrip

save_path: github-repos/MATLAB/fieldtrip-fieldtrip


text:
function x = ACR(p,n,alpha);
%ACR Upper percentiles critical value for test of single multivariate normal outlier.
% From the method given by Wilks (1963) and approaching to a F distribution
% function by the Yang and Lee (1987) formulation, we provide an m-file to
% get the critical value of the maximun squared Mahalanobis distance to detect
% outliers from a normal multivariate sample.
%
% Syntax: function x = ACR(p,n,alpha)
%   $$ The function's name is giving as a gratefull to Dr. Alvin C. Rencher for his
%      unvaluable contribution to multivariate statistics with his text 'Methods of
%      Multivariate Analysis'.$$
%
%     Inputs:
%          p - number of independent variables.
%          n - sample size.
%      alpha - significance level (default = 0.05).
%
%     Output:
%          x - critical value of the maximun squared Mahalanobis distance.
%
% We can generate all the critical values of the maximun squared Mahalanobis
% distance presented on the Table XXXII of by Barnett and Lewis (1978) and
% Table A.6 of Rencher (2002). Also with any given significance level (alpha).
%
% Example: For p = 3; n = 25; alpha=0.01;
%
% Calling on Matlab the function:
%                ACR(p,n,alpha)
%
% Answer is:
%
%     13.1753
%
%  Created by A. Trujillo-Ortiz, R. Hernandez-Walls, A. Castro-Perez and K. Barba-Rojo
%             Facultad de Ciencias Marinas
%             Universidad Autonoma de Baja California
%             Apdo. Postal 453
%             Ensenada, Baja California
%             Mexico.
%             atrujo@uabc.mx
%
%  Copyright. August 20, 2006.
%
%  To cite this file, this would be an appropriate format:
%  Trujillo-Ortiz, A., R. Hernandez-Walls, A. Castro-Perez and K. Barba-Rojo. (2006).
%    ACR:Upper percentiles critical value for test of single multivariate normal outlier.
%    A MATLAB file. [WWW document]. URL http://www.mathworks.com/matlabcentral/
%    fileexchange/loadFile.do?objectId=12161
%
%  References:
%  Barnett, V. and Lewis, T. (1978), Outliers on Statistical Data.
%           New-York:John Wiley & Sons.
%  Rencher, A. C. (2002), Methods of Multivariate Analysis. 2nd. ed.
%            New-Jersey:John Wiley & Sons. Chapter 13 (pp. 408-450).
%  Wilks, S. S. (1963), Multivariate Statistical Outliers. Sankhya,
%            Series A, 25: 407-426.
%  Yang, S. S. and Lee, Y. (1987), Identification of a Multivariate
%            Outlier. Presented at the Annual  Meeting of the American
%            Statistical Association, San Francisco, August 1987.
%

if nargin < 3,
   alpha = 0.05; %(default)
end;

if (alpha <= 0 | alpha >= 1)
   fprintf('Warning: significance level must be between 0 and 1\n');
   return;
end;

if nargin < 2,
   error('Requires at least two input arguments.');
   return;
end;

a = alpha;
Fc = finv(1-a/n,p,n-p-1); %F distribution critical value with p and n-p-1 degrees of freedom using the Bonferroni correction.
ACR = (p*(n-1)^2*Fc)/(n*(n-p-1)+(n*p*Fc)); % = ((-1*((1/(1+(Fc*p/(n-p-1))))-1))*((n-1)^2))/n;
x = ACR;

return,

author: Sable

repo: mcbench-benchmarks


text:
function [predict_label,accuracy] = jddt(x_train,y_train,x_test,y_test,options)
%%jddt:packaged decision tree from Matlab,just for easier use.
%%==============================================================================
%%input:
%%------x_train,...,y_test  :   training and testing sets.                               [required]
%%------options             :   some options to build the tree,default is null.    [not required]

%%output:
%%------predict_label       :   predicted label vector for test case.
%%------accuracy            :   accuracy
%%==============================================================================
	predict_label = [];
    accuracy = 0;
	switch nargin
		case 4
			tre = fitctree(x_train,y_train);
	        predict_label = tre.predict(x_test);
			accuracy = mean(predict_label == y_test);
		case 5
			tre = fitctree(x_train,y_train,options);
			predict_label = tre.predict(x_test);
			accuracy = mean(predict_label == y_test);
		otherwise
			fprintf('++++++Fatal error!Please check the input!');
            return
	end
end

author: jindongwang

repo: activityrecognition


text:
function [pred] = stackedAEPredict(theta, inputSize, hiddenSize, numClasses, netconfig, data)

% stackedAEPredict: Takes a trained theta and a test data set,
% and returns the predicted labels for each example.

% theta: trained weights from the autoencoder
% visibleSize: the number of input units
% hiddenSize:  the number of hidden units *at the 2nd layer*
% numClasses:  the number of categories
% data: Our matrix containing the training data as columns.  So, data(:,i) is the i-th training example.

% Your code should produce the prediction matrix
% pred, where pred(i) is argmax_c P(y(c) | x(i)).

%% Unroll theta parameter

% We first extract the part which compute the softmax gradient
softmaxTheta = reshape(theta(1:hiddenSize*numClasses), numClasses, hiddenSize);

% Extract out the "stack"
stack = params2stack(theta(hiddenSize*numClasses+1:end), netconfig);

%% ---------- YOUR CODE HERE --------------------------------------
%  Instructions: Compute pred using theta assuming that the labels start
%                from 1.

depth = numel(stack);
z = cell(depth+1,1);
a = cell(depth+1, 1);
a{1} = data;

for layer = (1:depth)
  z{layer+1} = stack{layer}.w * a{layer} + repmat(stack{layer}.b, [1, size(a{layer},2)]);
  a{layer+1} = sigmoid(z{layer+1});
end

[~, pred] = max(softmaxTheta * a{depth+1});

% -----------------------------------------------------------

end

% You might find this useful
function sigm = sigmoid(x)
    sigm = 1 ./ (1 + exp(-x));
end

author: zellyn


text:
function plotAbsolute(simOutputArray, Xref)
% plotAbsolute Plot absolute position and velocity from simulation output
%       This function plots the absolute position and velocity of the ACC
%       vehicle as well as the tracking vehicle for all the simulation
%       cases.
%
% Author : Ajinkya Khade, askhade@ncsu.edu

% List of y-axis labels for the 2 subplots
ylabelArray = {'Absolute Position (m)', 'Absolute Velocity (m/s)'};

% List of titles for the 2 subplots
titleArray  = {'(a)', '(b)', '(c)', '(d)'};

% List of line colors to be used for the different simulation cases
lineColorArray = {'k', 'b', 'r', 'm'};

% initializing array to store plot handles
h = zeros(2, length(simOutputArray));

% empty cell array to store legend entries
legendLog = {};

figure('units','normalized','outerposition',[0 0 1 1])

% plotting data for each simulation object stored in array
for i = 1:length(simOutputArray)

    tplot = 0:simOutputArray(i).ts:simOutputArray(i).tsim;              % Array containing simulation time steps
    Nsim = floor(simOutputArray(i).tsim/simOutputArray(i).ts) + 1;      % Number of time steps in simulation

    % calculating absolute position and velocity
    yplot = simOutputArray(i).empc(1:2,:) + Xref(1:2,1:end-1);
    yplot(1,:) = yplot(1,:) - simOutputArray(i).sivd;

    % Searching for point where relative distance becomes
    % positive, indicating a collision
    tcInd = find((simOutputArray(i).empc(1,:) - simOutputArray(i).sivd) > 0.0001, 1);

    % Setting point of collision to end point - this is just to prevent
    % errors because of the way the code works
    if isempty(tcInd)
        tcInd = Nsim;
    end

    % plotting position and velocity on different subplots
    for subplotNum = 1:2
        subplot(2,1,subplotNum)

        hold on; grid on;

        h(subplotNum,2*i-1) = plot(tplot(1:tcInd-1), yplot(subplotNum,1:tcInd-1),'LineStyle', '-', 'Color', lineColorArray{i});
        h(subplotNum,2*i)   = plot(tplot(1:tcInd-1), Xref(subplotNum,1:tcInd-1),'LineStyle', '--', 'Color', lineColorArray{i});

        % if collision is detected, use different line styles before and
        % after collision
        if tcInd < Nsim
            plot(tplot(tcInd), yplot(subplotNum,tcInd), 'xk','MarkerSize', 12);
            plot(tplot(tcInd), Xref(subplotNum,tcInd),  'xk','MarkerSize', 12);
            plot(tplot(tcInd+1:end), yplot(subplotNum,tcInd+1:end), 'LineStyle', '-.', 'Color', lineColorArray{i});
            plot(tplot(tcInd+1:end), Xref(subplotNum,tcInd+1:end-1),'LineStyle', ':',  'Color', lineColorArray{i});
        end

        hold off

        xlabel('Time (s)', 'FontSize', 12);
        ylabel(ylabelArray{subplotNum}, 'FontSize', 12);
        title ( titleArray{subplotNum}, 'FontSize', 14);

    end

    legendLog = [legendLog, ['ACC vehicle - ', simOutputArray(i).displayname], ['Target vehicle - ', simOutputArray(i).displayname]];

end

% Adding legend entries
for subPlotNum = 1:2
    legend(h(subPlotNum,:), legendLog);
end

end

author: ajinkya-khade


text:
function [rhoMin,rhoMax] = rhoRange(sR)
% compute range of the polar angle of a spherical region

if isempty(sR.N) || ...
    (length(sR.N) == 1 && ~isnull(sR.N.z) && sR.alpha == 0)

  rhoMin = 0;
  rhoMax = 2*pi;
  return
end

% antipodal should not increase spherical region
sR.antipodal = false;

% discretisation
omega = linspace(0,2*pi,361);

% start with equator
v = vector3d('theta',pi/2,'rho',omega);
rho = v.rho(sR.checkInside(v));

% cylce through boundary
for i = 1:length(sR.N)

  b = vector3d('theta',acos(sR.alpha(i)),'rho',omega);

  rot = rotation.map(zvector,sR.N(i));

  b = rot * b;

  % remove points close to north and south
  % as we can not determine rho very well
  b(abs(b.theta-pi/2)>pi/2-1e-4)= [];

  rho = [rho,b.rho(sR.checkInside(b))]; %#ok<AGROW>

end

rho = sort(mod(rho,2*pi));

% find all holes in the rho list
ind = find(abs(diff(rho))>20*degree);

% maybe there is also a hole in zero
if rho(end)-rho(1)<340*degree, ind = [ind, length(rho)]; end

if isempty(ind)

  if isempty(rho)
    rhoMin = 0;
    rhoMax = 2*pi;
  else
    rhoMin = min(rho);
    rhoMax = max(rho);
  end

else
  rhoMin = rho(mod(ind([end,1:end-1]),length(rho))+1);
  rhoMax = rho(ind);

  ind = rhoMin > rhoMax;
  rhoMin(ind) = rhoMin(ind) - 2*pi;

end

author: mtex-toolbox

repo: mtex

save_path: github-repos/MATLAB/mtex-toolbox-mtex


text:
function [merged_timestamps, merged_samples, merged_fs] = ...
    merge_sensor_data(timestamps, samples, offsets, fs)

    num_devices = length(samples);

    shift = max(offsets) - offsets;

    % trim recordings according to offsets
    % figure; hold all;
    for i = 1:num_devices
        if ~isempty(timestamps)
            trimmed_timestamps{i} = timestamps{i}(shift(i)+1:end);
        end

        trimmed_samples{i} = samples{i}(shift(i)+1:end);
        % plot(trimmed_samples{i});
    end
    % title('Trimmed signals');

    if ~isempty(timestamps)
        merged_timestamps = interleave_vectors(trimmed_timestamps);
    else
        merged_timestamps = [];
    end
    merged_samples = interleave_vectors(trimmed_samples);
    merged_fs = fs * num_devices;
    % [~, gyro_merged] = interpolate_samples(merged_timestamps, gyro_merged);
end

author: yueyuzhao

repo: gyrophone

save_path: github-repos/MATLAB/yueyuzhao-gyrophone


text:
% This demo script runs the SRDCF tracker on the included "Couple" video.

% Load video information
video_path = 'sequences/Couple';
% video_path = 'D:/Users/sliay/research/drone_benchmark/car2';
[seq, ~] = load_video_info(video_path);

% Run SRDCF
results = run_SRDCF(seq);

author: flyers

repo: drone-tracking


text:
function edge = lineToEdge3d(line)
%LINETOEDGE3D Convert a 3D straight line to a 3D finite edge.
%
%   EDGE = lineToEdge3d(LINE)
%   Returns the edge with same origin as the line LINE, and with second
%   extremity corresponding to the addition of line origin and direction.
%   LINE is represented as [X0 Y0 Z0  DX DY DZ]
%   EDGE is represented as [X1 Y1 Z1  X2 Y2 Z2]
%
%   Example
%     line = [3 4 5  1 2 3];
%     edge = lineToEdge3d(line)
%     edge =
%          3   4   5   4   6   8
%
%   See also
%     lines3d, edges3d, edgeToLine3d

% ------
% Author: David Legland
% E-mail: david.legland@inra.fr
% Created: 2019-05-07, using Matlab 9.6.0.1072779 (R2019a)
% Copyright 2019-2022 INRA - Cepia Software Platform

edge = [line(:, 1:3) line(:,1:3)+line(:,4:6)];

author: mattools

repo: matGeom

save_path: github-repos/MATLAB/mattools-matGeom


text:
function [ ap, info ] = dppfa ( ap, n )

%*****************************************************************************80
%
%% DPPFA factors a real symmetric positive definite matrix in packed form.
%
%  Discussion:
%
%    DPPFA is usually called by DPPCO, but it can be called
%    directly with a saving in time if RCOND is not needed.
%
%  Packed storage:
%
%    The following program segment will pack the upper
%    triangle of a symmetric matrix.
%
%      k = 0
%      do j = 1, n
%        do i = 1, j
%          k = k + 1
%          ap(k) = a(i,j)
%        end
%      end
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 June 2005
%
%  Author:
%
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Dongarra, Moler, Bunch and Stewart,
%    LINPACK User's Guide,
%    SIAM, (Society for Industrial and Applied Mathematics),
%    3600 University City Science Center,
%    Philadelphia, PA, 19104-2688.
%    ISBN 0-89871-172-X
%
%  Parameters:
%
%    Input, real AP(N*(N+1)/2), the packed form of a symmetric matrix A.
%    The columns of the upper triangle are stored sequentially in a
%    one-dimensional array.
%
%    Input, integer N, the order of the matrix.
%
%    Output, real AP(N*(N+1)/2), an upper triangular matrix R, stored
%    in packed form, so that A = R'*R.
%
%    Output, integer INFO, error flag.
%    0, for normal return.
%    K, if the leading minor of order K is not positive definite.
%
  info = 0;
  jj = 0;

  for j = 1 : n

    s = 0.0;
    kj = jj;
    kk = 0;

    for k = 1 : j-1

      kj = kj + 1;
      t = ap(kj) - ddot ( k-1, ap(kk+1:kk+k-1), 1, ap(jj+1:jj+k-1), 1 );
      kk = kk + k;
      t = t / ap(kk);
      ap(kj) = t;
      s = s + t * t;

    end

    jj = jj + j;
    s = ap(jj) - s;

    if ( s <= 0.0 )
      info = j;
      return
    end

    ap(jj) = sqrt ( s );

  end

  return
end


text:
classdef spotColorKey < orientationColorKey
  %
  %   Detailed explanation goes here

  properties
    center
    color
    psi
  end

  methods
    function oM = spotColorKey(varargin)
      oM = oM@orientationColorKey(varargin{:});

      oM.center = get_option(varargin,'center',orientation.id(oM.CS1));
      oM.CS1 = oM.center.CS;
      oM.color = get_option(varargin,'color',[1 0 0]);
      oM.psi = get_option(varargin,'kernel',...
        SO3DeLaValleePoussinKernel('halfwidth',get_option(varargin,'halfwidth',10*degree)));
    end

    function rgb = orientation2color(oM,ori)

      s = size(ori);
      rgb = ones([s,3]);

      for k=1:length(oM.center)

        w = oM.psi.eval(dot(ori,oM.center(k)))./oM.psi.eval(1);

        cdata = rgb2hsv(repmat(oM.color(k,:),length(ori),1));
        cdata(:,2) = w(:).*cdata(:,2);
        cdata = reshape(hsv2rgb(cdata),[s,3]);
        rgb = rgb.*cdata;
      end
    end
  end
end


text:
function [pv, pstd, cv, cstd, kv, kstd, loopout] = bruteboot(time_as)
    % function [pv, pstd, cv, cstd, kv, kstd, loopout] = bruteboot(time_as);
    % ----------------------------------------------------------------------
    % bootstrap analysis of Omori parameters calculated by bruteforce.m
    %
    % Input parameters:
    %   time_as     Delay times [days]
    %
    % Output parameters:
    %   pv / pstd   p value / standard deviation
    %   cv / cstd   c value / standard deviation
    %   kv / kstd   k value / standard deviation
    %   loopout     contains all results
    %
    % Samuel Neukomm
    % July 30, 2002

    time_as = sort(time_as);
    bootloops = 50; % number of bootstrap samples
    n = length(time_as);
    loopout = [];
    for j = 1:bootloops
        clear newtas
        randnr = ceil(rand(n,1)*n);
        i = (1:n)';
        newtas(i,:) = time_as(randnr(i),:); % bootstrap sample
        [pval, cval, kval] = bruteforce(sort(newtas)); % bruteforce.m is called
        loopout = [loopout; pval cval kval];
    end

    pv = round(100*mean(loopout(:,1)))/100;
    pstd = round(100*std(loopout(:,1)))/100;

    cv = round(100*mean(loopout(:,2)))/100;
    cstd = round(100*std(loopout(:,2)))/100;

    kv = round(10*mean(loopout(:,3)))/10;
    kstd = round(10*std(loopout(:,3)))/10;

    % unreasonable parameter values -> no result
    if pv < 0.6 | pv > 2.3 | cv < 0.01 | cv > 3 | cv < cstd | pv < pstd | kv < kstd
        pv = nan; pstd = nan;
        cv = nan; cstd = nan;
        kv = nan; kstd = nan;
    end
end

author: CelsoReyes


text:
function y=hav(x)
%%HAV Compute the haversine of x. The haversine arises in navigation
%     problems. As in [1], it is just sin(x/2).^2. Haversines tend to arise
%     in navigation problems.
%
%INPUTS: x A numeric matrix.
%
%OUTPUTS: y The haversine of x. y has the same dimensionality as x.
%
%REFERENCES:
%[1] Weisstein, Eric W. "Haversine." From MathWorld--A Wolfram Web
%    Resource. https://mathworld.wolfram.com/Haversine.html
%
%October 2022 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

y=sin(x/2).^2;

end

%LICENSE:
%
%The source code is in the public domain and not licensed or under
%copyright. The information and software may be used freely by the public.
%As required by 17 U.S.C. 403, third parties producing copyrighted works
%consisting predominantly of the material produced by U.S. government
%agencies must provide notice with such work(s) identifying the U.S.
%Government material incorporated and stating that such material is not
%subject to copyright protection.
%
%Derived works shall not identify themselves in a manner that implies an
%endorsement by or an affiliation with the Naval Research Laboratory.
%
%RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE
%SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY THE NAVAL
%RESEARCH LABORATORY FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE ACTIONS
%OF RECIPIENT IN THE USE OF THE SOFTWARE.

author: USNavalResearchLaboratory

repo: TrackerComponentLibrary


text:
function sitem = cfg2struct(item)

% function sitem = cfg2struct(item)
% Return a struct containing all fields of item plus a field type. This is
% the method suitable for entry classes.
%
% This code is part of a batch job configuration system for MATLAB. See
%      help matlabbatch
% for a general overview.
%_______________________________________________________________________
% Copyright (C) 2007 Freiburg Brain Imaging

% Volkmar Glauche
% $Id: cfg2struct.m 1716 2008-05-23 08:18:45Z volkmar $

rev = '$Rev: 1716 $'; %#ok

% Get parent struct, re-classify as field 'type'
sitem = cfg2struct(item.cfg_item);
sitem.type = class(item);

% Need to cycle through added fields
fn = mysubs_fields;
for k = 1:numel(fn)
    sitem.(fn{k}) = item.(fn{k});
end;


text:
function [ Elements, varargout ] = ply_read ( Path, Str )

%*****************************************************************************80
%
%% PLY_READ reads a PLY 3D data file.
%
%   [DATA,COMMENTS] = PLY_READ(FILENAME) reads a version 1.0 PLY file
%   FILENAME and returns a structure DATA.  The fields in this structure
%   are defined by the PLY header; each element type is a field and each
%   element property is a subfield.  If the file contains any comments,
%   they are returned in a cell string array COMMENTS.
%
%   [TRI,PTS] = PLY_READ(FILENAME,'tri') or
%   [TRI,PTS,DATA,COMMENTS] = PLY_READ(FILENAME,'tri') converts vertex
%   and face data into triangular connectivity and vertex arrays.  The
%   mesh can then be displayed using the TRISURF command.
%
%   Note: This function is slow for large mesh files (+50K faces),
%   especially when reading data with list type properties.
%
%   Example:
%   [Tri,Pts] = PLY_READ('cow.ply','tri');
%   trisurf(Tri,Pts(:,1),Pts(:,2),Pts(:,3));
%   colormap(gray); axis equal;
%
%  Discussion:
%
%    The original version of this program had a mistake that meant it
%    did not properly triangulate files whose faces were not already triangular.
%    This has been corrected (JVB, 25 February 2007).
%
%    Glenn Ramsey pointed out and corrected a problem that occurred
%    with an uninitialized value of Type2, 27 August 2012.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 August 2012
%
%  Author:
%
%    Pascal Getreuer 2004
%
%  Parameters:
%
%  Local Parameters:
%
%    COMMENTS, any comments from the file.
%
%    ELEMENTCOUNT, the number of each type of element in file.
%
%    ELEMENTS, the element data.
%
%    PROPERTYTYPES, the element property types.
%
%    SIZEOF, size in bytes of each type.
%

%
%  Open the input file in "read text" mode.
%
  [ fid, Msg ] = fopen ( Path, 'rt' );

  if ( fid == -1 )
    error ( Msg );
  end

  Buf = fscanf ( fid, '%s', 1 );

  if ( ~strcmp ( Buf, 'ply' ) )
    fclose ( fid );
    error('Not a PLY file.');
  end
%
%  Read the header.
%
  Position = ftell(fid);
  Format = '';
  NumComments = 0;
  Comments = {};
  NumElements = 0;
  NumProperties = 0;
  Elements = [];
  ElementCount = [];
  PropertyTypes = [];
  ElementNames = {};  % list of element names in the order they are stored in the file
  PropertyNames = [];  % structure of lists of property names

  while ( 1 )
%
%  Read a line from the file.
%
    Buf = fgetl ( fid );
    BufRem = Buf;
    Token = {};
    Count = 0;
%
%  Split the line into tokens.
%
    while ( ~isempty(BufRem) )

      [ tmp, BufRem ] = strtok(BufRem);
%
%  Count the tokens.
%
      if ( ~isempty ( tmp ) )
        Count = Count + 1;
        Token{Count} = tmp;
      end

    end
%
%  Parse the line.
%
    if ( Count )

      switch lower ( Token{1} )
%
%  Read the data format.
%
      case 'format'

        if ( 2 <= Count )

          Format = lower ( Token{2} );

          if ( Count == 3 & ~strcmp ( Token{3}, '1.0' ) )
            fclose ( fid );
            error('Only PLY format version 1.0 supported.');
          end
        end
%
%  Read a comment.
%
      case 'comment'

        NumComments = NumComments + 1;
        Comments{NumComments} = '';
        for i = 2 : Count
          Comments{NumComments} = [Comments{NumComments},Token{i},' '];
        end
%
%  Read an element name.
%
      case 'element'

        if ( 3 <= Count )

          if ( isfield(Elements,Token{2}) )
            fclose ( fid );
            error(['Duplicate element name, ''',Token{2},'''.']);
          end

          NumElements = NumElements + 1;
          NumProperties = 0;
          Elements = setfield(Elements,Token{2},[]);
          PropertyTypes = setfield(PropertyTypes,Token{2},[]);
          ElementNames{NumElements} = Token{2};
          PropertyNames = setfield(PropertyNames,Token{2},{});
          CurElement = Token{2};
          ElementCount(NumElements) = str2double(Token{3});

          if ( isnan(ElementCount(NumElements)) )
            fclose ( fid );
            error(['Bad element definition: ',Buf]);
          end

        else

          error(['Bad element definition: ',Buf]);

        end
%
%  Read an element property.
%
      case 'property'

        if ( ~isempty(CurElement) & Count >= 3 )

          NumProperties = NumProperties + 1;
          eval(['tmp=isfield(Elements.',CurElement,',Token{Count});'],...
            'fclose(fid);error([''Error reading property: '',Buf])');

          if ( tmp )
            error(['Duplicate property name, ''',CurElement,'.',Token{2},'''.']);
          end
%
%  Add property subfield to Elements.
%
          eval(['Elements.',CurElement,'.',Token{Count},'=[];'], ...
            'fclose(fid);error([''Error reading property: '',Buf])');
%
%  Add property subfield to PropertyTypes and save type.
%
          eval(['PropertyTypes.',CurElement,'.',Token{Count},'={Token{2:Count-1}};'], ...
            'fclose(fid);error([''Error reading property: '',Buf])');
%
%  Record property name order.
%
          eval(['PropertyNames.',CurElement,'{NumProperties}=Token{Count};'], ...
            'fclose(fid);error([''Error reading property: '',Buf])');

         else

           fclose ( fid );

           if ( isempty(CurElement) )
             error(['Property definition without element definition: ',Buf]);
           else
             error(['Bad property definition: ',Buf]);
           end

         end
%
%  End of header.
%
        case 'end_header'
          break;

      end
    end
  end
%
%  Set reading for specified data format.
%
  if ( isempty ( Format ) )
    warning('Data format unspecified, assuming ASCII.');
    Format = 'ascii';
  end

  switch Format

    case 'ascii'
      Format = 0;
    case 'binary_little_endian'
      Format = 1;
    case 'binary_big_endian'
      Format = 2;
    otherwise
      fclose ( fid );
      error(['Data format ''',Format,''' not supported.']);

  end
%
%  Read the rest of the file as ASCII data...
%
  if ( ~Format )
    Buf = fscanf ( fid, '%f' );
    BufOff = 1;
  else
%
%  ...or, close the file, and reopen in "read binary" mode.
%
    fclose ( fid );
%
%  Reopen the binary file as LITTLE_ENDIAN or BIG_ENDIAN.
%
    if ( Format == 1 )
      fid = fopen ( Path, 'r', 'ieee-le.l64' );
    else
      fid = fopen ( Path, 'r', 'ieee-be.l64' );
    end
%
%  Find the end of the header again.
%  Using ftell on the old handle doesn't give the correct position.
%
    BufSize = 8192;
    Buf = [ blanks(10), char(fread(fid,BufSize,'uchar')') ];
    i = [];
    tmp = -11;

    while ( isempty(i) )

      i = findstr(Buf,['end_header',13,10]);   % look for end_header + CR/LF
      i = [i,findstr(Buf,['end_header',10])];  % look for end_header + LF

      if ( isempty(i) )
        tmp = tmp + BufSize;
        Buf = [Buf(BufSize+1:BufSize+10),char(fread(fid,BufSize,'uchar')')];
      end

    end
%
%  seek to just after the line feed
%
    fseek ( fid, i + tmp + 11 + (Buf(i + 10) == 13), -1 );

  end
%
%  Read element data.
%
%  PLY and MATLAB data types (for fread)
%
  PlyTypeNames = {'char','uchar','short','ushort','int','uint','float','double', ...
    'char8','uchar8','short16','ushort16','int32','uint32','float32','double64'};

  MatlabTypeNames = {'schar','uchar','int16','uint16','int32','uint32','single','double'};

  SizeOf = [1,1,2,2,4,4,4,8];

  for i = 1 : NumElements
%
%  get current element property information
%
    eval(['CurPropertyNames=PropertyNames.',ElementNames{i},';']);
    eval(['CurPropertyTypes=PropertyTypes.',ElementNames{i},';']);
    NumProperties = size(CurPropertyNames,2);

%   fprintf('Reading %s...\n',ElementNames{i});
%
%  Read ASCII data.
%
    if ( ~Format )

      for j = 1 : NumProperties

        Token = getfield(CurPropertyTypes,CurPropertyNames{j});

        if ( strcmpi(Token{1},'list') )
          Type(j) = 1;
        else
          Type(j) = 0;
        end
%
%  Glenn Ramsey 20120827
%  Initialise Type2{} to prevent uninitialised value error.
%
        Type2{j} = '';

      end
%
%  Parse the buffer.
%
      if ( ~any(Type) )

         % no list types

        Data = reshape ( ...
          Buf(BufOff:BufOff+ElementCount(i)*NumProperties-1), ...
          NumProperties, ElementCount(i) )';

        BufOff = BufOff + ElementCount(i) * NumProperties;

      else

        ListData = cell(NumProperties,1);

        for k = 1 : NumProperties
          ListData{k} = cell(ElementCount(i),1);
        end
%
% list type
%
        for j = 1 : ElementCount(i)
          for k = 1 : NumProperties

            if ( ~Type(k) )
              Data(j,k) = Buf(BufOff);
              BufOff = BufOff + 1;
            else
              tmp = Buf(BufOff);
              ListData{k}{j} = Buf(BufOff+(1:tmp))';
              BufOff = BufOff + tmp + 1;
            end

          end
        end

      end
%
%  Read binary data.
%
    else
% translate PLY data type names to MATLAB data type names
      ListFlag = 0;  % = 1 if there is a list type
      SameFlag = 1;     % = 1 if all types are the same

      for j = 1 : NumProperties

        Token = getfield(CurPropertyTypes,CurPropertyNames{j});
%
%  Non-list type.
%
        if ( ~strcmp(Token{1},'list' ) )

          tmp = rem(strmatch(Token{1},PlyTypeNames,'exact')-1,8)+1;

          if ( ~isempty(tmp) )

            TypeSize(j) = SizeOf(tmp);
            Type{j} = MatlabTypeNames{tmp};
            TypeSize2(j) = 0;
            Type2{j} = '';

            SameFlag = SameFlag & strcmp(Type{1},Type{j});

          else

            fclose(fid);
            error(['Unknown property data type, ''',Token{1},''', in ', ...
              ElementNames{i},'.',CurPropertyNames{j},'.']);

          end

        else           % list type

          if ( length(Token) == 3 )

            ListFlag = 1;
            SameFlag = 0;
            tmp = rem(strmatch(Token{2},PlyTypeNames,'exact')-1,8)+1;
            tmp2 = rem(strmatch(Token{3},PlyTypeNames,'exact')-1,8)+1;

            if ( ~isempty(tmp) & ~isempty(tmp2) )
              TypeSize(j) = SizeOf(tmp);
              Type{j} = MatlabTypeNames{tmp};
              TypeSize2(j) = SizeOf(tmp2);
              Type2{j} = MatlabTypeNames{tmp2};
            else
              fclose(fid);
              error(['Unknown property data type, ''list ',Token{2},' ',Token{3},''', in ', ...
                ElementNames{i},'.',CurPropertyNames{j},'.']);
            end

          else

            fclose(fid);
            error(['Invalid list syntax in ',ElementNames{i},'.',CurPropertyNames{j},'.']);

          end

        end

      end

% read file

      if ( ~ListFlag )
%
%  No list types, all the same type (fast)
%
        if ( SameFlag )

          Data = fread(fid,[NumProperties,ElementCount(i)],Type{1})';
%
%  No list types, mixed type.
%
        else

          Data = zeros(ElementCount(i),NumProperties);

          for j = 1 : ElementCount(i)
            for k = 1 : NumProperties
              Data(j,k) = fread(fid,1,Type{k});
            end
          end

        end

      else

        ListData = cell(NumProperties,1);

        for k = 1 : NumProperties
          ListData{k} = cell(ElementCount(i),1);
        end

        if ( NumProperties == 1 )

          BufSize = 512;
          SkipNum = 4;
          j = 0;
%
%  List type, one property (fast if lists are usually the same length)
%
          while ( j < ElementCount(i) )

            BufSize = min(ElementCount(i)-j,BufSize);
            Position = ftell(fid);
%
%  Read in BufSize count values, assuming all counts = SkipNum
%
            [Buf,BufSize] = fread(fid,BufSize,Type{1},SkipNum*TypeSize2(1));
            Miss = find(Buf ~= SkipNum);     % find first count that is not SkipNum
            fseek(fid,Position + TypeSize(1),-1);   % seek back to after first count

            if ( isempty(Miss) )
% all counts are SkipNum
              Buf = fread(fid,[SkipNum,BufSize],[int2str(SkipNum),'*',Type2{1}],TypeSize(1))';
              fseek(fid,-TypeSize(1),0);     % undo last skip

              for k = 1:BufSize
                ListData{1}{j+k} = Buf(k,:);
              end

              j = j + BufSize;
              BufSize = floor(1.5*BufSize);

            else
%
%  Some counts are SkipNum.
%
              if ( 1 < Miss(1) )

                Buf2 = fread(fid,[SkipNum,Miss(1)-1],[int2str(SkipNum),'*',Type2{1}],TypeSize(1))';

                for k = 1:Miss(1)-1
                  ListData{1}{j+k} = Buf2(k,:);
                end

                j = j + k;

              end
%
%  Read in the list with the missed count.
%
              SkipNum = Buf(Miss(1));
              j = j + 1;
              ListData{1}{j} = fread(fid,[1,SkipNum],Type2{1});
              BufSize = ceil(0.6*BufSize);

            end
          end

        else
%
%  List type(s), multiple properties (slow)
%
          Data = zeros(ElementCount(i),NumProperties);

          for j = 1:ElementCount(i)
            for k = 1:NumProperties

              if ( isempty(Type2{k}) )
                Data(j,k) = fread(fid,1,Type{k});
              else
                tmp = fread(fid,1,Type{k});
                ListData{k}{j} = fread(fid,[1,tmp],Type2{k});
              end

            end
          end
        end
      end
    end
%
%  Put data into Elements structure
%
    for k = 1 : NumProperties

      if ( ( ~Format && ~isempty(Type(k)) ) || (Format && isempty(Type2{k})) )
        eval(['Elements.',ElementNames{i},'.',CurPropertyNames{k},'=Data(:,k);']);
      else
        eval(['Elements.',ElementNames{i},'.',CurPropertyNames{k},'=ListData{k};']);
      end

    end

  end

  clear Data
  clear ListData;

  fclose ( fid );
%
%  Output the data as a triangular mesh pair.
%
  if ( ( nargin > 1 && strcmpi(Str,'Tri') ) || nargout > 2 )
%
%  Find vertex element field
%
    Name = {'vertex','Vertex','point','Point','pts','Pts'};
    Names = [];

    for i = 1 : length(Name)

      if ( any ( strcmp ( ElementNames, Name{i} ) ) )
        Names = getfield(PropertyNames,Name{i});
        Name = Name{i};
        break;
      end

    end

    if ( any(strcmp(Names,'x')) & any(strcmp(Names,'y')) & any(strcmp(Names,'z')) )
      eval(['varargout{1}=[Elements.',Name,'.x,Elements.',Name,'.y,Elements.',Name,'.z];']);
    else
      varargout{1} = zeros(1,3);
    end
    varargout{1} = varargout{1}';

    varargout{2} = Elements;
    varargout{3} = Comments;
    Elements = [];
%
% Find face element field
%
    Name = {'face','Face','poly','Poly','tri','Tri'};
    Names = [];

    for i = 1 : length(Name)
      if ( any(strcmp(ElementNames,Name{i})) )
        Names = getfield(PropertyNames,Name{i});
        Name = Name{i};
        break;
      end
    end

    if ( ~isempty(Names) )
      % find vertex indices property subfield
      PropertyName = {'vertex_indices','vertex_indexes','vertex_index','indices','indexes'};

      for i = 1 : length(PropertyName)
        if ( any(strcmp(Names,PropertyName{i})) )
          PropertyName = PropertyName{i};
          break;
        end
      end
%
%  Convert face index list to triangular connectivity.
%
      if ( ~iscell(PropertyName) )

        eval(['FaceIndices=varargout{2}.',Name,'.',PropertyName,';']);
        N = length(FaceIndices);
        Elements = zeros(3,N*2);
        Extra = 0;

        for k = 1 : N

          Elements(1:3,k) = FaceIndices{k}(1:3)';
%
%  The original code had an error in the following loop.
%
          for j = 4 : length(FaceIndices{k})
            Extra = Extra + 1;
            Elements(1,N + Extra) = FaceIndices{k}(1);
            Elements(2,N + Extra) = FaceIndices{k}(j-1);
            Elements(3,N + Extra) = FaceIndices{k}(j);
          end

        end
%
%  Add 1 to each vertex value; PLY vertices are zero based.
%
        Elements = Elements(:,1:N+Extra) + 1;

      end
    end

  else

    varargout{1} = Comments;

  end

  return
end

author: OshriHalimi