Commit c399ed5c authored by Mark Winter's avatar Mark Winter

Merge branch 'master' into opensource/master

# Conflicts:
#	readme.md
parents 95554c77 9467936c
Pipeline #154 skipped
......@@ -13,6 +13,9 @@ bin/*.prj
bin/*.txt
segmentationData/
# Ignore segmentation help function used in compiled LEVER versions.
CompiledSegHelp.m
#ignore thumbnails created by windows
Thumbs.db
#Ignore files build by Visual Studio
......@@ -58,3 +61,12 @@ src/MATLAB/*.csv
src/MATLAB/filmstrip/*/*
src/MATLAB/*.exe
bin64/*.exe
*.ipdb
*.iobj
*.exp
*.tlog
*.idb
*.opendb
src/c/Output/TrackerMex/Debug_x64/
src/c/Output/TrackerMex/Release_x64/
src/c/trackerMex.mexw64
No preview for this file type
No preview for this file type
function graphStruct = BuildDependencyGraph(chkPath, bRecurseExternal)
if ( ~exist('chkPath','var') || isempty(chkPath) )
chkPath = pwd();
end
if ( ~exist('bRecurseExternal','var'))
bRecurseExternal = true;
end
%% Make sure we get back to our current dir even on error.
oldDir = cd(chkPath);
cleanupObj = onCleanup(@()(cd(oldDir)));
%%
filenames = getAllFiles(chkPath);
%% Initialize sparse matrix assuming a fanout of about 10x
n = length(filenames);
graphStruct = struct('nodes',{filenames}, 'graph',{sparse([],[],[],n,n,10*n)});
graphStruct = recursiveGetDeps(chkPath, graphStruct, filenames, bRecurseExternal);
graphStruct = sortNodes(chkPath,graphStruct);
end
function graphStruct = sortNodes(localPath, graphStruct)
bLocal = strncmp(localPath,graphStruct.nodes, length(localPath));
localIdx = find(bLocal);
externalIdx = find(~bLocal);
%% Sort lexicographically, but all local functions are first.
[~,localSrt] = sort(graphStruct.nodes(bLocal));
[~,externalSrt] = sort(graphStruct.nodes(~bLocal));
srtIdx = [localIdx(localSrt); externalIdx(externalSrt)];
graphStruct.nodes = graphStruct.nodes(srtIdx);
graphStruct.graph = graphStruct.graph(srtIdx,:);
graphStruct.graph = graphStruct.graph(:,srtIdx);
end
function graphStruct = recursiveGetDeps(localPath,graphStruct, checkNames, bRecurseExternal)
if ( isempty(checkNames) )
return;
end
newEntries = {};
matRoot = matlabroot();
% Get single-link dependencies
for i=1:length(checkNames)
[fList,pList] = matlab.codetools.requiredFilesAndProducts(checkNames{i}, 'toponly');
toolboxes = arrayfun(@(x)(fullfile(matRoot,'toolbox',x.Name)),pList, 'UniformOutput',false);
selfIdx = find(strcmp(checkNames{i},fList));
if ( isempty(selfIdx) )
selfIdx = 1;
fList = [checkNames(i) fList];
end
newNodes = [fList.'; toolboxes.'];
newGraph = createCallGraph(selfIdx, newNodes);
newStruct = struct('nodes',{newNodes},'graph',{newGraph});
[graphStruct,addedNodes] = Dev.MergeGraphStruct(graphStruct, newStruct);
newEntries = [newEntries; addedNodes];
end
% Don't recurse through external dependencies
bMatlab = strncmp(matRoot,newEntries, length(matRoot));
newEntries = newEntries(~bMatlab);
if ( ~bRecurseExternal )
bNewLocal = strncmp(localPath,newEntries, length(localPath));
newEntries = newEntries(bNewLocal);
end
graphStruct = recursiveGetDeps(localPath,graphStruct, newEntries, bRecurseExternal);
end
function callGraph = createCallGraph(callerIdx,newNodes)
jIdx = setdiff(1:length(newNodes),callerIdx);
iIdx = repmat(callerIdx,1,length(jIdx));
callGraph = sparse(iIdx,jIdx, ones(1,length(jIdx)), length(newNodes),length(newNodes), length(jIdx));
end
function fullNames = getAllFiles(dirName)
matlabFiles = what(dirName);
funcFileNames = vertcat(matlabFiles.m);
funcFileNames = [funcFileNames; vertcat(matlabFiles.mex)];
fullNames = cellfun(@(x)(fullfile(dirName,x)), funcFileNames, 'UniformOutput',false);
for i=1:length(matlabFiles.packages)
pkgFullNames = getAllFiles(fullfile(dirName, ['+' matlabFiles.packages{i}]));
fullNames = [fullNames; pkgFullNames];
end
for i=1:length(matlabFiles.classes)
classDir = fullfile(dirName, ['@' matlabFiles.classes{i}]);
if ( ~exist(classDir,'dir') )
continue;
end
classFullNames = getAllFiles(classDir);
fullNames = [fullNames; classFullNames];
end
end
function toolboxMap = BuildToolboxMap()
toolboxRoot = toolboxdir('');
toolboxMap = containers.Map('keyType','char', 'valueType','any');
% Ignore fixPoint, because
toolboxList = dir(toolboxRoot);
bInvalidName = arrayfun(@(x)(strcmp(x.name,'.') || strcmp(x.name,'..') || strcmp(x.name,'fixpoint')), toolboxList);
bValidDir = ~bInvalidName & (vertcat(toolboxList.isdir) > 0);
toolboxList = toolboxList(bValidDir);
% Always add local/shared directory to matlab
toolboxMap('MATLAB') = {fullfile(toolboxRoot,'local');fullfile(toolboxRoot,'shared')};
for i=1:length(toolboxList)
verStruct = ver(toolboxList(i).name);
if ( isempty(verStruct) )
continue;
end
if ( isKey(toolboxMap,verStruct.Name) )
toolboxMap(verStruct.Name) = [toolboxMap(verStruct.Name); {fullfile(toolboxRoot,toolboxList(i).name)}];
else
toolboxMap(verStruct.Name) = {fullfile(toolboxRoot,toolboxList(i).name)};
end
end
end
function CheckMEXSynch(checkGraph)
[checkOut checkIn] = mexDijkstra('debugAllEdges');
checkOut = sortrows(checkOut);
checkIn = sortrows(checkIn);
if ( any(checkOut(:) ~= checkIn(:)) )
error('In/Out MEX Edges are out of synch.');
end
if ( exist('checkGraph','var') )
[rcm, ccm] = find(checkGraph > 0);
graphInd = sub2ind(size(checkGraph), rcm, ccm);
checkMAT = [rcm ccm full(checkGraph(graphInd))];
checkMAT = sortrows(checkMAT);
if ( any(checkOut(:) ~= checkMAT(:)) )
error('MEX Edges out of synch with Matlab.');
end
end
end
\ No newline at end of file
......@@ -2,10 +2,10 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Copyright 2011 Andrew Cohen, Eric Wait and Mark Winter
% Copyright 2011-2016 Andrew Cohen
%
% This file is part of LEVer - the tool for stem cell lineaging. See
% https://pantherfile.uwm.edu/cohena/www/LEVer.html for details
% http://n2t.net/ark:/87918/d9rp4t for details
%
% LEVer is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
......@@ -25,35 +25,18 @@
function CompileLEVer(forceVersion)
totalTime = tic();
% Try to set up git for the build, give a warning about checking the
% fallback file if we can't find git.
bFoundGit = Dev.SetupGit();
if ( ~bFoundGit )
questionStr = sprintf('%s\n%s','Cannot find git you should verify the fallback file version info before building.','Are you sure you wish to continue with the build?');
result = questdlg(questionStr,'Build Warning','Yes','No','No');
if ( strcmpi(result,'No') )
return;
end
end
% Give a messagebox warning if there are uncommitted changes.
% Note: even committed changes may not have been pushed to server.
[status,result] = system('git status --porcelain');
if ( status == 0 && (length(result) > 1) )
questionStr = sprintf('%s\n%s','There are uncommitted changes in your working directory','Are you sure you wish to continue with the build?');
result = questdlg(questionStr,'Build Warning','Yes','No','No');
if ( strcmpi(result,'No') )
return;
end
end
if ( ~exist('forceVersion', 'var') )
Dev.MakeVersion();
else
Dev.MakeVersion(0, forceVersion);
if ( ~exist('forceVersion','var') )
forceVersion = '';
end
%% General compiler setup: Deals with version updates and pulls external dependencies
initStruct = Dev.InitCompiler('LEVER',forceVersion);
%% Build FrameSegmentor help information into a function for use in compiled LEVER
Dev.MakeSegHelp();
%% Setup visual studio for MEX compilation
[vsStruct comparch] = setupCompileTools();
bindir = '..\..\bin';
......@@ -65,11 +48,15 @@ function CompileLEVer(forceVersion)
mkdir(bindir);
end
%% Compile all MEX files
outputFiles = {};
newOutput = compileMEX('mexMAT', vsStruct);
outputFiles = [outputFiles; {newOutput}];
newOutput = compileMEX('Tracker', vsStruct);
outputFiles = [outputFiles; {newOutput}];
newOutput = compileMEX('mexDijkstra', vsStruct);
outputFiles = [outputFiles; {newOutput}];
......@@ -82,49 +69,18 @@ function CompileLEVer(forceVersion)
newOutput = compileMEX('mexHashData', vsStruct);
outputFiles = [outputFiles; {newOutput}];
newOutput = compileEXE('MTC', vsStruct, bindir);
outputFiles = [outputFiles; {newOutput}];
[toolboxStruct externalStruct] = Dev.GetExternalDependencies();
if ( ~isempty(externalStruct.deps) )
fprintf('ERROR: Some local functions have external dependencies\n');
for i=1:length(externalStruct.deps)
fprintf('[%d] %s\n', i, externalStruct.deps{i});
for j=1:length(externalStruct.funcs{i})
if ( ~isempty(externalStruct.callers{i}{j}) )
for k=1:length(externalStruct.callers{i}{j})
localName = Dev.GetLocalName(externalStruct.callers{i}{j}{k});
fprintf(' %s calls: %s\n', localName, externalStruct.funcs{i}{j});
end
end
end
fprintf('------\n');
end
% error('External dependencies cannot be packaged in a MATLAB executable');
questionStr = sprintf('%s\n%s','Possible external dependencies were found in project, you should verify all these functions are local before continuing the build.','Are you sure you wish to continue?');
result = questdlg(questionStr,'External Dependency Warning','Continue','Cancel','Cancel');
if ( strcmpi(result,'Cancel') )
return;
end
end
% temporarily remove any startup scripts that would normally be run by matlabrc
enableStartupScripts(false);
%% Compile LEVER, Segmentor, and batch LEVER_SegAndTrackFolders.
addImgs = {'+UI\backFrame.png'; '+UI\forwardFrame.png'; '+UI\pause.png';'+UI\play.png';'+UI\stop.png'};
newOutput = compileMATLAB('LEVer', bindir, addImgs, toolboxStruct.deps);
newOutput = compileMATLAB('LEVer', bindir, addImgs, initStruct.toolboxList);
outputFiles = [outputFiles; {newOutput}];
newOutput = compileMATLAB('LEVER_SegAndTrackFolders', bindir, {}, toolboxStruct.deps);
newOutput = compileMATLAB('LEVER_SegAndTrackFolders', bindir, {}, initStruct.toolboxList);
outputFiles = [outputFiles; {newOutput}];
newOutput = compileMATLAB('Segmentor', bindir, {}, toolboxStruct.deps);
newOutput = compileMATLAB('Segmentor', bindir, {}, initStruct.toolboxList);
outputFiles = [outputFiles; {newOutput}];
enableStartupScripts(true);
fprintf('\n');
% mcrfile = mcrinstaller();
......@@ -133,16 +89,16 @@ function CompileLEVer(forceVersion)
bIsEXE = cellfun(@(x)(~isempty(x)), strfind(lower(outputFiles), '.exe'));
exeOutputs = outputFiles(bIsEXE);
verSuffix = Helper.GetVersion('file');
zip(fullfile(bindir,['LEVer' verSuffix '.zip']), [exeOutputs; {'*.bat'}], bindir);
% verSuffix = Dev.GetVersion('file');
% zip(fullfile(bindir,['LEVer' verSuffix '.zip']), [exeOutputs; {'*.bat'}], bindir);
toc(totalTime)
end
function [vsStruct comparch] = setupCompileTools()
vsStruct.vstoolroot = getenv('VS100COMNTOOLS');
vsStruct.vstoolroot = getenv('VS140COMNTOOLS');
if ( isempty(vsStruct.vstoolroot) )
error('Cannot compile MTC and mexMAT without Visual Studio 2010');
error('Cannot compile MEX files without Visual Studio 2015');
end
setenv('MATLAB_DIR', matlabroot());
......@@ -152,12 +108,8 @@ function [vsStruct comparch] = setupCompileTools()
vsStruct.buildbits = '64';
vsStruct.buildenv = fullfile(vsStruct.vstoolroot,'..','..','vc','bin','amd64','vcvars64.bat');
vsStruct.buildplatform = 'x64';
elseif ( strcmpi(comparch,'win32') )
vsStruct.buildbits = '32';
vsStruct.buildenv = fullfile(vsStruct.vstoolroot,'..','..','vc','bin','vcvars32.bat');
vsStruct.buildplatform = 'win32';
else
error('Only windows 32/64-bit builds are currently supported');
error('Only windows 64-bit builds are currently supported');
end
system(['"' vsStruct.buildenv '"' ]);
......@@ -208,8 +160,8 @@ function outputFile = compileMATLAB(projectName, bindir, extrasList, toolboxList
end
extrasList = vertcat({'LEVER_logo.tif';
'+Segmentation\FrameSegmentor_*.m';
'+Helper\GetVersion.m';
'+Helper\VersionInfo.m'}, extrasList);
'+Dev\GetVersion.m';
'+Dev\VersionInfo.m'}, extrasList);
extraCommand = '';
if ( ~isempty(extrasList) )
......@@ -237,45 +189,3 @@ function outputFile = compileMATLAB(projectName, bindir, extrasList, toolboxList
fprintf('Done (%f sec)\n', toc(compileTime));
end
function enableStartupScripts(bEnable)
searchPrefix = '';
renamePrefix = 'disabled_';
if ( bEnable )
searchPrefix = 'disabled_';
renamePrefix = '';
end
searchName = [searchPrefix 'startup.m'];
newName = [renamePrefix 'startup.m'];
startupScripts = findFilesInPath(searchName, userpath);
for i=1:length(startupScripts)
scriptPath = fileparts(startupScripts{i});
movefile(startupScripts{i}, fullfile(scriptPath,newName));
end
end
function fullNames = findFilesInPath(filename, searchPaths)
fullNames = {};
chkPaths = [];
while ( ~isempty(searchPaths) )
[newPath remainder] = strtok(searchPaths, pathsep);
if ( isempty(newPath) )
searchPaths = remainder;
continue;
end
chkPaths = [chkPaths; {newPath}];
searchPaths = remainder;
end
for i=1:length(chkPaths)
chkFullPath = fullfile(chkPaths{i}, filename);
if ( exist(chkFullPath, 'file') )
fullNames = [fullNames; {chkFullPath}];
end
end
end
This diff is collapsed.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Copyright 2011-2016 Andrew Cohen
%
% This file is part of LEVer - the tool for stem cell lineaging. See
% http://n2t.net/ark:/87918/d9rp4t for details
%
% LEVer is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% LEVer is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with LEVer in file "gnu gpl v3.txt". If not, see
% <http://www.gnu.org/licenses/>.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function helpStruct = FrameSegHelp(funcName)
helpStruct = [];
SupportedTypes = Load.GetSupportedCellTypes();
segInfo = [SupportedTypes.segRoutine];
segFuncs = arrayfun(@(x)(char(x.func)), segInfo, 'UniformOutput',false);
funcIdx = find(strcmp(segFuncs, funcName));
if ( isempty(funcIdx) )
return;
end
if ( isdeployed() )
helpStruct = Dev.CompiledSegHelp(funcName);
return;
end
chkInfo = segInfo(funcIdx);
chkName = char(chkInfo.func);
helpStruct.func = chkName;
helpStruct.summary = '';
helpStruct.paramHelp = cell(length(chkInfo.params),1);
helpString = help(chkName);
if ( isempty(helpString) )
helpString = chkName;
end
%% Get a segmentation summary from function help.
tokMatch = regexp(helpString,'^\s*FrameSegmentor_*\w*\s*-\s*(.+?)^\s*$', 'once','tokens','lineanchors');
if ( isempty(tokMatch) )
helpLines = strsplit(helpString,'\n');
funcSummary = escapeString(strtrim(helpLines{1}));
else
funcSummary = escapeString(tokMatch{1});
end
%% Get parameter help if available in function documentation.
helpStruct.summary = funcSummary;
for i=1:length(chkInfo.params)
paramName = chkInfo.params(i).name;
helpStruct.paramHelp{i} = '';
tokMatch = regexp(helpString,['^\s*(' paramName '.+?)^\s*$'], 'once','tokens','lineanchors');
if ( ~isempty(tokMatch) )
helpStruct.paramHelp{i} = escapeString(tokMatch{1});
end
end
end
% Escape inStr so that safeStr will reproduce inStr when passed as a format string to sprintf()
function safeStr = escapeString(inStr)
escStr = {'%%','\\','\a','\b','\f','\n','\r','\t','\v'};
escChars = num2cell(sprintf([escStr{:}]));
escStr = [{''''''},escStr];
escChars = [{''''},escChars];
escMap = containers.Map(escChars,escStr);
safeStr = '';
for i=1:length(inStr)
nextChar = inStr(i);
if ( isKey(escMap,nextChar) )
nextChar = escMap(nextChar);
end
safeStr = [safeStr nextChar];
end
end
% [repoName,commitHash] = GetCommitInfo(inPath)
%
function [repoName,commitHash] = GetCommitInfo(inPath)
remoteUrl = Dev.GitRemote(inPath,'origin');
repoName = '';
tokMatch = regexp(remoteUrl,'\w+@[\w\-.]+:[\w\-.]+/([\w\-]+\.git)', 'tokens','once');
if ( ~isempty(tokMatch) )
repoName = tokMatch{1};
end
commitHash = Dev.GitCommitHash(inPath);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Copyright 2011-2016 Andrew Cohen
%
% This file is part of LEVer - the tool for stem cell lineaging. See
% http://n2t.net/ark:/87918/d9rp4t for details
%
% LEVer is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by