526 lines
16 KiB
Matlab
526 lines
16 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 easySuffix
|
|
global scansDir
|
|
global easyResultsDir
|
|
global easyResultsDirName
|
|
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
|
|
|
|
demo=1;
|
|
if demo
|
|
disp('Running in demo mode');
|
|
disp('Initialized variables:');
|
|
whos;
|
|
end
|
|
|
|
fprintf('This script name: %s\n', easyFileName);
|
|
|
|
% Set scansDir (project scans directory) intelligently
|
|
if exist('PROJECT', 'var') && ~isempty(getenv('PROJECT'))
|
|
scansDir=getenv('PROJECT');
|
|
fprintf('Using project path: %s from environment variable PROJECT\n', scansDir);
|
|
disp('This usually indicates that we are in standalone mode');
|
|
elseif exist('SCANS_DIR', 'var') && ~isempty(getenv('SCANS_DIR'))
|
|
scansDir=getenv('SCANS_DIR');
|
|
fprintf('Using scans directory: %s from environment variable SCANS_DIR\n', scansDir);
|
|
disp('This usually indicates that we are in module mode');
|
|
else
|
|
% Change these when modifying EASY_DIR in workflow
|
|
fprintf('Beginning parent scans directory search\n');
|
|
fprintf('This usually indicates that we are in stand-alone mode without PROJECT or SCANS_DIR environment variables\n');
|
|
dirsToScan={
|
|
fullfile(parentDir,'..', '..', 'scans'),
|
|
fullfile(parentDir, '..', '..', 'ExpJobs'),
|
|
fullfile('/mnt/data/scans'),
|
|
fullfile('/mnt/data/ExpJobs'),
|
|
fullfile(parentDir, '..', 'demo', '20240727_hartmanlab_demo_project')
|
|
};
|
|
for d=dirsToScan
|
|
if exist(d, 'dir')
|
|
subDirs=dir(d);
|
|
if ~isempty(subDirs)
|
|
fprintf('Found a non-empty parent scans directory in our list: %s\n', d);
|
|
fprintf('Scanning inside for a project scan directory\n');
|
|
[~, sortedIndices]=sort(datenum({dirs.date}), 'descend'); % sort by newest first
|
|
sortedDirs=dirs{sortedIndices};
|
|
scansDir=sortedDirs{1};
|
|
fprintf('Selected newest project scans directory: %s\n', scansDir);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
% Sanity check and warning
|
|
if exist('PROJECT_USER', 'var') && ~isempty(getenv('PROJECT_USER'))
|
|
if ~equal(getenv('PROJECT_USER'), userName)
|
|
disp("WARNING: PROJECT_USER does not match the current namespace");
|
|
end
|
|
end
|
|
|
|
% Allow module to override hardcoded default EASY directory
|
|
if exist('EASY_DIR','var') && ~isempty(getenv('EASY_DIR'))
|
|
EASY_DIR=fullfile(getenv('EASY_DIR'));
|
|
if ~strcmp(easyDir, EASY_DIR) % sanity check
|
|
disp("WARNING: EASY_DIR does not match this script's hardcoded EASY location");
|
|
disp("This is probably OK but if strange beahvior arises, we'll need to fix it in code");
|
|
easyDir=EASY_DIR;
|
|
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
|
|
|
|
% If we don't have tan EASY_SUFFIX from the module, generate it from scansDir
|
|
if exist('EASY_SUFFIX', 'var') && ~isempty(getenv('EASY_SUFFIX'))
|
|
easySuffix=getenv('EASY_SUFFIX');
|
|
else
|
|
% The following is a way to parse the project name from the scansDir
|
|
[ ~, dirName]=fileparts(scansDir);
|
|
parts=strsplit(dirName, '_');
|
|
scansDate=parts{1};
|
|
scansUserName=parts{2};
|
|
easySuffix=strjoin(parts(3:end), '_');
|
|
% Might as well check this too for fun
|
|
if ~strcmp(userName, scansUserName)
|
|
disp('WARNING: userName does not match scansUserName');
|
|
disp("This usually means that you are attempting to run an EASY analysis on another user's project data scans");
|
|
end
|
|
% For happiness
|
|
if strcmp(todayStr, scansDate)
|
|
disp("Early bird gets the worm");
|
|
end
|
|
end
|
|
|
|
if (exist('EASY_RESULTS_DIR', 'var') && ~isempty(getenv('EASY_RESULTS_DIR')))
|
|
easyResultsDir=fullfile(getenv('EASY_RESULTS_DIR'));
|
|
if exist(easyResultsDir, 'dir')
|
|
fprintf('WARNING: EASY results dir %s already exists\n', easyResultsDir);
|
|
disp('Files in this directory may be overwritten');
|
|
end
|
|
fprintf('Using output directory: %s from environment variable EASY_RESULTS_DIR\n', easyResultsDir);
|
|
else
|
|
easyResultsDirName=strcat('Results_',todayStr,'_',userName,'_',easySuffix);
|
|
easyResultsDir=fullfile(scansDir,easyResultsDirName);
|
|
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
|
|
|
|
if exist('MASTER_PLATE_FILE', 'var') && ~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(scansDir,'MasterPlateFiles',strcat('MasterPlate_', easySuffix,'.xlsx'));
|
|
if exist(mp, 'file')
|
|
masterPlateFile=mp;
|
|
fprintf('Using drug media file: %s from internal logic\n', masterPlateFile);
|
|
else
|
|
fprintf('WARNING: Have you created a MasterPlate_ file in %s/MasterPlateFiles/?\n', scansDir);
|
|
end
|
|
end
|
|
|
|
if exist('DRUG_MEDIA_FILE', 'var') && ~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
|
|
% Try to find MasterPlate_ file on our own
|
|
dm=fullfile(scansDir,'MasterPlateFiles',strcat('DrugMedia_', easySuffix,'.xlsx'));
|
|
if exist(mp, '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/MasterPlateFiles/?\n', scansDir);
|
|
end
|
|
end
|
|
|
|
matDir=fullfile(easyResultsDir,'matResults');
|
|
if ~exist(matDir, 'dir')
|
|
mkdir(matDir);
|
|
end
|
|
matFile=fullfile(matDir,strcat(easyResultsDirName,'.mat'));
|
|
% Pulled these out of par4GblFnc8c
|
|
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');
|
|
mpdmFile=fullfile(matDir,'MPDM.mat');
|
|
|
|
% Decent time to print some helpful vars
|
|
if demo
|
|
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 scansDir
|
|
|
|
% 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('scansDir','var') && ~isempty(scansDir)
|
|
set(fhconsole,'Name', sprintf('EASYconsole - %s', scansDir));
|
|
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 easyResultsDirName
|
|
global fhconsole
|
|
global scan
|
|
global userName
|
|
|
|
% Create a new experiment
|
|
try
|
|
questdlg('\fontsize{20} NAME the file and NAVIGATE to the directory with the image folders.','File Creation','OK', struct('Default','OK','Interpreter','tex'));
|
|
[inputFile,inputPath]=uiputfile('.mat');
|
|
inputFileName=strrep(inputFile,'.mat','');
|
|
easyResultsDirName=strcat('Results_',todayStr,'_',userName,'_',inputFileName);
|
|
|
|
% Set paths
|
|
scansDir=fullfile(inputPath);
|
|
easyResultsDir=fullfile(scansDir,easyResultsDirName);
|
|
matDir=fullfile(easyResultsDir,'matResults');
|
|
matFile=fullfile(matDir,strcat(todayStr,'_',userName,'_',inputFile));
|
|
|
|
%***Added for 'parfor global' to preallocate 'scan' structure 20-0123*****
|
|
nlist=dir(fullfile(scansDir,'*'));
|
|
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', 'Fotos/BkUp'};
|
|
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 easyResultsDir
|
|
global easyPath
|
|
global fhconsole
|
|
|
|
try
|
|
questdlg('Load results .mat from ../ExpJobs/YourJob/Results/matResults/','File Creation','OK', struct('Default','OK','Interpreter','tex'));
|
|
[inputFile,inputPath]=uigetfile('.mat','Open Experiment folder and data storage .mat file name','MultiSelect','off');
|
|
matDir=fullfile(inputPath);
|
|
matFile=fullfile(inputPath,inputFile);
|
|
load(matFile);
|
|
easyResultsDir=fullfile(matDir,'..');
|
|
scansDir=fullfile(matDir,'..', '..');
|
|
point
|
|
|
|
% TODO this is pretty hacky and needs something more explicit
|
|
if isfolder(fullfile(matDir, '..','..','1')) % If Inovation Vrobot Then
|
|
try
|
|
exist(pointMapsFile, 'file')
|
|
load(pointMapsFile);
|
|
catch
|
|
try
|
|
load(fullfile(easyPath,'NImParameters.mat')); % hardcoded default
|
|
catch
|
|
disp("Could not load the NImParameters.mat file")
|
|
end
|
|
end
|
|
else % If Epson 10Plate Scans Then>
|
|
if exist(fullfile(pointMapsResultsDir,'ImParameters.mat'), 'file')
|
|
load(fullfile(pointMapsResultsDir,'ImParameters.mat'));
|
|
else
|
|
try
|
|
load(fullfile(easyPath,'ImParameters.mat'));
|
|
catch
|
|
disp("Could not load the ImParameters.mat file");
|
|
end
|
|
end
|
|
else
|
|
disp('WARNING: cannot find project scans');
|
|
end
|
|
|
|
bkupDir=fullfile(matDir,'BkUp');
|
|
if ~exist(bkupDir, 'dir')
|
|
mkkdir(bkupDir);
|
|
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 %similar but semicolons removed to restore so cmdLine display info.
|
|
%Dgen241010qhtcp %par4global -convert 1x1cell of 384cells to be like previous 1x384 cells CFparameter
|
|
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 |