Files
hartman-server/qhtcp-workflow/apps/matlab/easy/EASYconsole.m

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