File refactoring

This commit is contained in:
2024-07-27 17:56:56 -04:00
parent bb103a6f9a
commit bcc2d875f2
56 changed files with 19243 additions and 103 deletions

View File

@@ -0,0 +1,537 @@
% 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
dirToScan=fullfile(parentDir,'..','ExpJobs'); % hardcoded relative to easy script dir TODO: if we change pj layout this will change
if exist(dirToScan, 'dir')
dirs=dir(fullfile(dirToScan, 'dir')); % filter for dirs only
[~, sortedIndices]=sort(datenum({dirs.date}), 'descend'); % sort by newest first
sortedDirs=dirs{sortedIndices};
scansDir=sortedDirs{1};
disp('Beginning in newest project scans directory');
fprintf('Using scans directory: %s from hardcoded relative path\n', scansDir);
disp('This usually indicates that we are in stand-alone mode without PROJECT or SCANS_DIR environment variables');
else
scansDir=fullfile(parentDir, '..', 'demo', '20240727_hartmanlab_demo_project');
if exist(scansDir, 'dir')
demo=1;
fprintf('Using scans directory: %s from hardcoded absolute path to demo project\n', scansDir);
else
fprintf('Error: demo project %s not found\n', scansDir);
disp('Attempting to continue but this may get ugly');
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
% To remove?
% Try to enter
% function returnStartDir
% global scansDir
% global startDir
% try
% cd(scansDir)
% catch
% msgbox('Failed to enter the project directory so starting search from where we started.');
% cd(startDir)
% 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 FUNCTION %%
% 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