508 lines
15 KiB
Matlab
508 lines
15 KiB
Matlab
% Launch the MATLAB EASY console
|
|
% Updated 240727 Bryan C Roessler to improve file operations and portability
|
|
|
|
function varargout = EASYconsole(varargin)
|
|
global easyDir
|
|
global projectName
|
|
global projectScansDir
|
|
global easyResultsDir
|
|
global easyProjectName
|
|
global fotosResultsDir
|
|
global figsResultsDir
|
|
global pointMapsResultsDir
|
|
global pointMapsFile
|
|
global printResultsDir
|
|
global matDir
|
|
global matFile
|
|
global drugMediaFile
|
|
global masterPlateFile
|
|
global mpdmFile
|
|
global userName
|
|
global srchRange
|
|
global searchRangeFile
|
|
|
|
% Initialize some variables from matlab
|
|
easyPath=which(mfilename);
|
|
[easyDir,easyFileName]=fileparts(easyPath);
|
|
easyDir=fullfile(easyDir);
|
|
[parentDir, ~]=fileparts(easyDir);
|
|
parentDir=fullfile(parentDir); % ../easy/apps
|
|
userName=getenv('USER');
|
|
dt=datetime;
|
|
todayStr=char(dt, 'yyyyMMdd'); % This should match the parent workflow script 'hardcode'
|
|
outDir=fullfile(parentDir, '..','..', 'out'); % This should match the parent workflow script 'hardcode'
|
|
|
|
debug=1;
|
|
if debug
|
|
disp('Running in debug mode');
|
|
disp('Initialized variables:');
|
|
whos;
|
|
end
|
|
|
|
fprintf('This script name: %s\n', easyFileName);
|
|
|
|
% Allow EASY_DIR env to override hardcoded default EASY directory
|
|
if ~isempty(getenv('EASY_DIR'))
|
|
ed=fullfile(getenv('EASY_DIR'));
|
|
if ~strcmp(easyDir, ed) % sanity check
|
|
disp("WARNING: EASY_DIR does not match this script's hardcoded EASY location");
|
|
disp("This is probably OK but this pathway is not well-tested");
|
|
easyDir=ed;
|
|
end
|
|
fprintf('Using EASY script directory: %s from environment variable EASY_DIR\n', easyDir);
|
|
else
|
|
fprintf('Using EASY script directory: %s from hardcoded default\n', easyDir);
|
|
end
|
|
|
|
whos
|
|
|
|
% Set projectScansDir intelligently
|
|
if ~isempty(getenv('PROJECT_SCANS_DIR'))
|
|
projectScansDir=fullfile(getenv('PROJECT_SCANS_DIR'));
|
|
if exist(projectScansDir, 'dir')
|
|
fprintf('Using scans directory: %s from environment variable PROJECT_SCANS_DIR\n', projectScansDir);
|
|
disp('This usually indicates that we are in module mode');
|
|
else
|
|
disp('WARNING: PROJECT_SCANS_DIR does not exist');
|
|
end
|
|
elseif ~isempty(getenv('PROJECT_NAME')) % for standalone mode
|
|
projectName=getenv('PROJECT_NAME');
|
|
projectScansDir=fullfile(parentDir, '..', '..', 'scans', projectName);
|
|
fprintf('Using project path: %s from environment variable PROJECT\n', projectScansDir);
|
|
disp('This usually indicates that we are in standalone mode');
|
|
else
|
|
% TODO Lots of hardcoded logic, this TODO is just a reminder to change this block
|
|
% when changing EASY and other variables in the parent script
|
|
fprintf('WARNING: Running in standalone mode without PROJECT or PROJECT_SCANS_DIR environment variables (not recommended)\n');
|
|
fprintf('Beginning parent scans directory search\n');
|
|
dirsToScan={
|
|
fullfile(parentDir, '..', '..', 'scans')
|
|
fullfile(parentDir, '..', '..', 'ExpJobs')
|
|
fullfile('mnt','data','scans')
|
|
fullfile('mnt','data', 'ExpJobs')
|
|
fullfile(parentDir, '..', '..', 'templates', 'scans-demo')
|
|
};
|
|
for i=1:length(dirsToScan)
|
|
d=dirsToScan(i);
|
|
d=char(d);
|
|
if exist(d, 'dir')
|
|
matchedDirs={};
|
|
subDirs=dir(d);
|
|
pattern='^\d{6}_.*_.*';
|
|
for i=1:length(subDirs)
|
|
if ~isempty(strmatch(subDirs(i).name, pattern))
|
|
matchedDirs{end+1}=subDirs(i).name;
|
|
end
|
|
end
|
|
whos
|
|
if ~isempty(matchedDirs)
|
|
fprintf('Using scansDir %s\n', char(d));
|
|
end
|
|
fprintf('Scanning inside %s for a project directory\n', d);
|
|
sortedMatchedDirs=sortrows(matchedDirs);
|
|
projectScansDir=fullfile(sortedMatchedDirs{end}); % select the latest dir (by date prefix)
|
|
fprintf('Using project scans directory: %s\n', char(projectScansDir));
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
% Get the name of the project
|
|
[~, projectName]=fileparts(projectScansDir);
|
|
|
|
% Set the run-specific EASY output directory
|
|
if ~isempty(getenv('EASY_RESULTS_DIR'))
|
|
easyResultsDir=fullfile(getenv('EASY_RESULTS_DIR'));
|
|
fprintf('Using output directory: %s from environment variable EASY_RESULTS_DIR\n', easyResultsDir);
|
|
else
|
|
easyProjectName=strcat(todayStr, '_',userName, '_', projectName);
|
|
easyResultsDir=fullfile(parentDir, '..', '..', 'out', projectName, 'easy', easyProjectName);
|
|
if exist(easyResultsDir, 'dir')
|
|
fprintf('WARNING: EASY results dir %s already exists\n', easyResultsDir);
|
|
disp('Files in this directory may be overwritten')
|
|
fprintf('Using output directory: %s\n', easyResultsDir);
|
|
end
|
|
end
|
|
|
|
% Get the name of the EASY project
|
|
if ~isempty(getenv('EASY_PROJECT_NAME'))
|
|
easyProjectName=getenv('EASY_PROJECT_NAME');
|
|
else
|
|
[~, easyProjectName]=fileparts(easyResultsDir);
|
|
end
|
|
|
|
% User sanity check and warning
|
|
if ~isempty(getenv('PROJECT_USER'))
|
|
if ~strcmp(getenv('PROJECT_USER'), userName)
|
|
disp("WARNING: PROJECT_USER does not match the current namespace");
|
|
end
|
|
end
|
|
|
|
if ~isempty(getenv('MASTER_PLATE_FILE'))
|
|
masterPlateFile=fullfile(getenv('MASTER_PLATE_FILE'));
|
|
fprintf('Using drug media file: %s from environment variable MASTER_PLATE_FILE\n', masterPlateFile);
|
|
else % try to find MasterPlate_ file on our own
|
|
mp=fullfile(easyResultsDir, strcat('MasterPlate_', projectName,'.xlsx'));
|
|
if exist(mp, 'file')
|
|
masterPlateFile=mp;
|
|
fprintf('Using master plate file: %s from internal logic\n', masterPlateFile);
|
|
else
|
|
fprintf('WARNING: Could not find MasterPlate file: %s\n', mp);
|
|
fprintf('WARNING: Have you created a MasterPlate_ file in %s', easyResultsDir);
|
|
end
|
|
end
|
|
|
|
if ~isempty(getenv('DRUG_MEDIA_FILE'))
|
|
drugMediaFile=fullfile(getenv('DRUG_MEDIA_FILE'));
|
|
fprintf('Using drug media file: %s from environment variable DRUG_MEDIA_FILE\n', drugMediaFile);
|
|
else
|
|
dm=fullfile(easyResultsDir, strcat('DrugMedia_', projectName,'.xlsx'));
|
|
if exist(dm, 'file')
|
|
drugMediaFile=dm;
|
|
fprintf('Using drug media file: %s from internal logic\n', drugMediaFile);
|
|
else
|
|
fprintf('WARNING: Have you created a DrugMedia_ file in %s?\n', easyResultsDir);
|
|
end
|
|
end
|
|
|
|
matDir=fullfile(easyResultsDir, 'matResults');
|
|
matFile=fullfile(matDir,easyProjectName,'.mat');
|
|
mpdmFile=fullfile(matDir,'MPDM.mat');
|
|
printResultsDir=fullfile(easyResultsDir,'PrintResults');
|
|
fotosResultsDir=fullfile(easyResultsDir,'Fotos');
|
|
figsResultsDir=fullfile(easyResultsDir,'figs');
|
|
pointMapsResultsDir=fullfile(easyResultsDir,'PTmats');
|
|
pointMapsFile=fullfile(pointMapsResultsDir,'NImParameters.mat');
|
|
oldPointMapsFile=fullfile(pointMapsResultsDir,'ImParameters.mat');
|
|
searchRangeFile=fullfile(fotosResultsDir,'CSearchRange.mat');
|
|
|
|
% Decent time to print some helpful vars
|
|
if debug
|
|
disp('Vars at end of main loop:')
|
|
whos;
|
|
end
|
|
|
|
% This can be removed, I think it should add the previous search range?
|
|
% Might be nice feature but can remove if it causes issues
|
|
% We are using searchRangeNum to hold old CSrchRange value(s)
|
|
if exist(searchRangeFile, 'file')
|
|
searchRangeNum=load(searchRangeFile);
|
|
end
|
|
|
|
% Add easyDir to the MATLAB path
|
|
% I have not idea if this is necessary or works but theoretically should
|
|
% reduce directory scoping issues when calling scripts w/o a path
|
|
addpath(easyDir);
|
|
|
|
% GUI interface design
|
|
gui_Singleton=1;
|
|
gui_State=struct(...
|
|
'gui_Name', mfilename, ...
|
|
'gui_Singleton', gui_Singleton, ...
|
|
'gui_OpeningFcn', @EASYconsole_OpeningFcn, ...
|
|
'gui_OutputFcn', @EASYconsole_OutputFcn, ...
|
|
'gui_LayoutFcn', [] , ...
|
|
'gui_Callback', []);
|
|
if nargin && ischar(varargin{1})
|
|
gui_State.gui_Callback=str2func(varargin{1});
|
|
end
|
|
|
|
if nargout
|
|
[varargout{1:nargout}]=gui_mainfcn(gui_State, varargin{:});
|
|
else
|
|
gui_mainfcn(gui_State, varargin{:});
|
|
end
|
|
end
|
|
|
|
% GUI
|
|
% Easyconcole_OpeningFcn executes just before the EASYconsole GUI is made visible.
|
|
% This function has no output args, see OutputFcn.
|
|
% hObject--handle to figure
|
|
% eventdata reserved - to be defined in a future version of MATLAB
|
|
% handles--structure with handles and user data (see GUIDATA)
|
|
% varargin--input arguments to EASYconsole (see VARARGIN)
|
|
function EASYconsole_OpeningFcn(hObject, ~, handles, varargin)
|
|
global fhconsole
|
|
global projectScansDir
|
|
|
|
% Choose default command line output for EASYconsole
|
|
handles.output=hObject;
|
|
|
|
% Update handles structure
|
|
guidata(hObject, handles);
|
|
|
|
%Figure header, Toolbar, etc. Setup
|
|
fhconsole=gcf;
|
|
set(fhconsole,'Toolbar','none');
|
|
fhconsole=gcf;
|
|
|
|
% Pulled this out of the opening function
|
|
% Seems better to wait until we have our vars set though?
|
|
if exist('projectScansDir','var') && ~isempty(projectScansDir)
|
|
set(fhconsole,'Name', sprintf('EASYconsole - %s', projectScansDir));
|
|
else
|
|
set(fhconsole,'Name','EASYconsole - No Active Experiment.')
|
|
end
|
|
end
|
|
|
|
% EASYconsole output
|
|
% Outputs from this function are returned to the command line.
|
|
% varargout--cell array for returning output args (see VARARGOUT);
|
|
% hObject--handle to figure
|
|
% eventdata reserved - to be defined in a future version of MATLAB
|
|
% handles--structure with handles and user data (see GUIDATA)
|
|
function varargout = EASYconsole_OutputFcn(~, ~, handles)
|
|
% Get default command line output from handles structure
|
|
varargout{1}=handles.output;
|
|
end
|
|
|
|
% Console button interfaces
|
|
% File Button Interface
|
|
function FileMenu_Callback(~, ~, ~)
|
|
% returnStartDir
|
|
end
|
|
|
|
% Load Experiment Button Interface
|
|
function LoadExp_Callback(~, ~, ~)
|
|
% returnStartDir
|
|
end
|
|
|
|
% New Experiment Button Interface
|
|
function NewExpDat_Callback(~, ~, ~)
|
|
global matDir
|
|
global matFile
|
|
global easyResultsDir
|
|
global easyProjectName
|
|
global fhconsole
|
|
global scan
|
|
global userName
|
|
global todayStr
|
|
|
|
% Create a new experiment
|
|
try
|
|
questdlg('Name the file and navigate to the directory with the image folders.','File Creation','OK', struct('Default','OK','Interpreter','tex'));
|
|
[matfile,easyResultsDir]=uiputfile('.mat');
|
|
inputFileName=strrep(inputFile,'.mat','');
|
|
|
|
[~, projectName]=fileparts(easyResultsDir);
|
|
% Set paths
|
|
matDir=fullfile(easyResultsDir,'matResults');
|
|
matFile=fullfile(matDir, projectName, '.mat');
|
|
|
|
% Added for 'parfor global' to preallocate 'scan' structure
|
|
nlist=dir(fullfile(projectScansDir,'*'));
|
|
nnn=0;
|
|
for n=1:size(nlist,1)
|
|
if (~isempty(str2num(nlist(n).name)))
|
|
nnn=nnn+1;
|
|
PnumLst(nnn)= (str2num(nlist(n).name));
|
|
sl(nnn,1)={(nlist(n).name)};
|
|
end
|
|
end
|
|
scanSize=size(sl,1);
|
|
scanMax=max(str2double(sl));
|
|
clear scan;
|
|
scan(scanMax)=struct(); % changed for parfor global 20_0118
|
|
save(matFile,'scan')
|
|
|
|
% create supporting dirs
|
|
% this is also in the workflow script but here for standalone mode
|
|
dirs={'PrintResults', 'CFfigs', 'Fotos'};
|
|
for i=1:length(dirs)
|
|
d=dirs{i};
|
|
if ~exist(fullfile(easyResultsDir, d), 'dir')
|
|
mkdir(fullfile(easyResultsDir, d));
|
|
end
|
|
end
|
|
|
|
% templateDirs are stored in the easy template directory
|
|
templates={'figs', 'PTmats'};
|
|
for i=1:length(templates)
|
|
d=dirs{i};
|
|
if ~exist(fullfile(easyResultsDir, d), 'dir')
|
|
copyfile((fullfile(easyDir,d)), (fullfile(easyResultsDir,d)));
|
|
end
|
|
end
|
|
|
|
clear sbdg % reduce possible retention of a previous job sdbg
|
|
sbdg= cell(1,scanMax);
|
|
save((fullfile(easyResultsDir,'Fotos','Nbdg')),'sbdg');
|
|
catch ME
|
|
fprintf('ERROR: %s\n', ME.message);
|
|
end
|
|
|
|
% set the title for fhconsole depending on existence
|
|
if exist('easyResultsDir','var') && ~isempty(easyResultsDir)
|
|
set(fhconsole,'Name',sprintf('EASYconsole - %s', easyResultsDir));
|
|
else
|
|
set(fhconsole,'Name','EASYconsole - Master Plate directory not selected.');
|
|
end
|
|
end
|
|
|
|
|
|
% Load a previous experiment
|
|
function LoadDatFile_Callback(~, ~, ~)
|
|
global matDir
|
|
global matFile
|
|
global projectName
|
|
global easyResultsDir
|
|
global easyProjectName
|
|
global easyPath
|
|
global fhconsole
|
|
|
|
try
|
|
questdlg('Load results .mat from ../out/project/','File Creation','OK', struct('Default','OK','Interpreter','tex'));
|
|
[matDir,matFile]=uigetfile('.mat','Open Experiment folder and data storage .mat file name','MultiSelect','off');
|
|
load(matFile);
|
|
easyResultsDir=fullfile(matDir,'..');
|
|
[~, projectName]=fileparts(easyResultsDir);
|
|
projectScansDir=fullfile(easyResultsDir, '..', '..', 'scans', projectName);
|
|
|
|
% TODO this is pretty hacky and needs something more explicit
|
|
if isfolder(fullfile(matDir, '..','..','1')) % If Inovation Vrobot Then
|
|
if load(pointMapsFile);
|
|
elseif load(fullfile(easyPath,'NImParameters.mat')); % hardcoded default
|
|
elseif load(fullfile(pointMapsResultsDir,'ImParameters.mat'));
|
|
elseif load(fullfile(easyPath,'ImParameters.mat'));
|
|
else
|
|
disp("Could not load the ImParameters.mat file");
|
|
end
|
|
else
|
|
disp('WARNING: cannot find project scans');
|
|
end
|
|
|
|
% Create supporting dirs
|
|
dirs={'PrintResults', 'figs', 'CFfigs', 'PTmats', 'Fotos'};
|
|
for i=1:length(dirs)
|
|
d=dirs{i};
|
|
if ~exist(fullfile(easyResultsDir, d), 'dir')
|
|
mkdir(fullfile(easyResultsDir, d));
|
|
end
|
|
end
|
|
catch
|
|
end
|
|
|
|
clear scan
|
|
|
|
if exist('easyResultsDir','var') && ~isempty(easyResultsDir)
|
|
fhconsole=gcf;
|
|
set(fhconsole,'Name',sprintf('EASYconsole - %s', easyResultsDir));
|
|
else
|
|
set(fhconsole,'Name','EASYconsole - Exp. Analysis NOT selected.');
|
|
end
|
|
end
|
|
|
|
% Callbacks
|
|
% 'Run' in the dropdown menu
|
|
function run_Callback(~, ~, ~)
|
|
end
|
|
|
|
function runPlateMapPintool_Callback(~, ~, ~)
|
|
try
|
|
NImapPT
|
|
catch
|
|
EASYconsole
|
|
end
|
|
end
|
|
|
|
function NImCFcombo_Callback(~, ~, ~)
|
|
try
|
|
par4Gbl_Main8c
|
|
EASYconsole
|
|
catch
|
|
EASYconsole
|
|
end
|
|
end
|
|
|
|
function runPlateImAnal_Callback(~, ~, ~)
|
|
try
|
|
NImStartupOnly
|
|
catch
|
|
EASYconsole
|
|
end
|
|
end
|
|
|
|
function PlateCFit_Callback(~, ~, ~)
|
|
% global matFile % TODO BCR not sure if needed
|
|
try
|
|
NCstart
|
|
catch
|
|
EASYconsole
|
|
end
|
|
end
|
|
|
|
function GenPrintouts_Callback(~, ~, ~)
|
|
end
|
|
|
|
function uploadExcelMP2DB_Callback(~, ~, ~)
|
|
end
|
|
|
|
function runDMPexcel_Callback(~, ~, ~)
|
|
try
|
|
DMPexcel2mat
|
|
catch
|
|
EASYconsole
|
|
end
|
|
end
|
|
|
|
function runResults_DBcombo_Callback(~, ~, ~)
|
|
try
|
|
DgenResults
|
|
catch ME
|
|
fprintf('Error in DgenResults: %s\n', ME.message);
|
|
EASYconsole
|
|
end
|
|
end
|
|
|
|
function Tools_Callback(~, ~, ~)
|
|
end
|
|
|
|
function runOverlayPlots_Callback(~, ~, ~)
|
|
try
|
|
DoverlayPlots2
|
|
EASYconsole
|
|
catch
|
|
EASYconsole
|
|
end
|
|
end
|
|
|
|
function runFotoStrip_Callback(~, ~, ~)
|
|
try
|
|
F_NImStartup_CentCir
|
|
EASYconsole
|
|
catch
|
|
EASYconsole
|
|
end
|
|
end
|
|
|
|
function runDisplayFig_Callback(~, ~, ~)
|
|
try
|
|
UfigDisplay
|
|
catch
|
|
EASYconsole
|
|
end
|
|
end
|
|
|
|
function runViewParameters_Callback(~, ~, ~)
|
|
try
|
|
catch
|
|
EASYconsole
|
|
end
|
|
end
|
|
|
|
function QkviewN_Callback(~, ~, ~)
|
|
try
|
|
QkviewImages
|
|
catch
|
|
EASYconsole
|
|
end
|
|
end
|
|
|
|
function CFdisplay_Callback(~, ~, ~)
|
|
try
|
|
NCsingleDisplay
|
|
EASYconsole
|
|
catch
|
|
EASYconsole
|
|
end
|
|
end |