EASYconsole.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. % Launch the MATLAB EASY console
  2. % Updated 240727 Bryan C Roessler to improve file operations and portability
  3. function varargout = EASYconsole(varargin)
  4. global easyDir
  5. global projectName
  6. global projectScansDir
  7. global easyResultsDir
  8. global easyProjectName
  9. global fotosResultsDir
  10. global figsResultsDir
  11. global pointMapsResultsDir
  12. global pointMapsFile
  13. global printResultsDir
  14. global matDir
  15. global matFile
  16. global drugMediaFile
  17. global masterPlateFile
  18. global mpdmFile
  19. global userName
  20. global srchRange
  21. global searchRangeFile
  22. % Initialize some variables from matlab
  23. easyPath=which(mfilename);
  24. [easyDir,easyFileName]=fileparts(easyPath);
  25. easyDir=fullfile(easyDir);
  26. [parentDir, ~]=fileparts(easyDir);
  27. parentDir=fullfile(parentDir); % ../easy/apps
  28. userName=getenv('USER');
  29. dt=datetime;
  30. todayStr=char(dt, 'yyyyMMdd'); % This should match the parent workflow script 'hardcode'
  31. outDir=fullfile(parentDir, '..','..', 'out'); % This should match the parent workflow script 'hardcode'
  32. debug=1;
  33. if debug
  34. disp('Running in debug mode');
  35. disp('Initialized variables:');
  36. whos;
  37. end
  38. fprintf('This script name: %s\n', easyFileName);
  39. % Allow EASY_DIR env to override hardcoded default EASY directory
  40. if ~isempty(getenv('EASY_DIR'))
  41. ed=fullfile(getenv('EASY_DIR'));
  42. if ~strcmp(easyDir, ed) % sanity check
  43. disp("WARNING: EASY_DIR does not match this script's hardcoded EASY location");
  44. disp("This is probably OK but this pathway is not well-tested");
  45. easyDir=ed;
  46. end
  47. fprintf('Using EASY script directory: %s from environment variable EASY_DIR\n', easyDir);
  48. else
  49. fprintf('Using EASY script directory: %s from hardcoded default\n', easyDir);
  50. end
  51. whos
  52. % Set projectScansDir intelligently
  53. if ~isempty(getenv('PROJECT_SCANS_DIR'))
  54. projectScansDir=fullfile(getenv('PROJECT_SCANS_DIR'));
  55. if exist(projectScansDir, 'dir')
  56. fprintf('Using scans directory: %s from environment variable PROJECT_SCANS_DIR\n', projectScansDir);
  57. disp('This usually indicates that we are in module mode');
  58. else
  59. disp('WARNING: PROJECT_SCANS_DIR does not exist');
  60. end
  61. elseif ~isempty(getenv('PROJECT_NAME')) % for standalone mode
  62. projectName=getenv('PROJECT_NAME');
  63. projectScansDir=fullfile(parentDir, '..', '..', 'scans', projectName);
  64. fprintf('Using project path: %s from environment variable PROJECT\n', projectScansDir);
  65. disp('This usually indicates that we are in standalone mode');
  66. else
  67. % TODO Lots of hardcoded logic, this TODO is just a reminder to change this block
  68. % when changing EASY and other variables in the parent script
  69. fprintf('WARNING: Running in standalone mode without PROJECT or PROJECT_SCANS_DIR environment variables (not recommended)\n');
  70. fprintf('Beginning parent scans directory search\n');
  71. dirsToScan={
  72. fullfile(parentDir, '..', '..', 'scans')
  73. fullfile(parentDir, '..', '..', 'ExpJobs')
  74. fullfile('mnt','data','scans')
  75. fullfile('mnt','data', 'ExpJobs')
  76. fullfile(parentDir, '..', '..', 'templates', 'scans-demo')
  77. };
  78. for i=1:length(dirsToScan)
  79. d=dirsToScan(i);
  80. d=char(d);
  81. if exist(d, 'dir')
  82. matchedDirs={};
  83. subDirs=dir(d);
  84. pattern='^\d{6}_.*_.*';
  85. for i=1:length(subDirs)
  86. if ~isempty(strmatch(subDirs(i).name, pattern))
  87. matchedDirs{end+1}=subDirs(i).name;
  88. end
  89. end
  90. whos
  91. if ~isempty(matchedDirs)
  92. fprintf('Using scansDir %s\n', char(d));
  93. end
  94. fprintf('Scanning inside %s for a project directory\n', d);
  95. sortedMatchedDirs=sortrows(matchedDirs);
  96. projectScansDir=fullfile(sortedMatchedDirs{end}); % select the latest dir (by date prefix)
  97. fprintf('Using project scans directory: %s\n', char(projectScansDir));
  98. break
  99. end
  100. end
  101. end
  102. % Get the name of the project
  103. [~, projectName]=fileparts(projectScansDir);
  104. % Set the run-specific EASY output directory
  105. if ~isempty(getenv('EASY_RESULTS_DIR'))
  106. easyResultsDir=fullfile(getenv('EASY_RESULTS_DIR'));
  107. fprintf('Using output directory: %s from environment variable EASY_RESULTS_DIR\n', easyResultsDir);
  108. else
  109. easyProjectName=strcat(todayStr, '_',userName, '_', projectName);
  110. easyResultsDir=fullfile(parentDir, '..', '..', 'out', projectName, 'easy', easyProjectName);
  111. if exist(easyResultsDir, 'dir')
  112. fprintf('WARNING: EASY results dir %s already exists\n', easyResultsDir);
  113. disp('Files in this directory may be overwritten')
  114. fprintf('Using output directory: %s\n', easyResultsDir);
  115. end
  116. end
  117. % Get the name of the EASY project
  118. if ~isempty(getenv('EASY_PROJECT_NAME'))
  119. easyProjectName=getenv('EASY_PROJECT_NAME');
  120. else
  121. [~, easyProjectName]=fileparts(easyResultsDir);
  122. end
  123. % User sanity check and warning
  124. if ~isempty(getenv('PROJECT_USER'))
  125. if ~strcmp(getenv('PROJECT_USER'), userName)
  126. disp("WARNING: PROJECT_USER does not match the current namespace");
  127. end
  128. end
  129. if ~isempty(getenv('MASTER_PLATE_FILE'))
  130. masterPlateFile=fullfile(getenv('MASTER_PLATE_FILE'));
  131. fprintf('Using drug media file: %s from environment variable MASTER_PLATE_FILE\n', masterPlateFile);
  132. else % try to find MasterPlate_ file on our own
  133. mp=fullfile(easyResultsDir, strcat('MasterPlate_', projectName,'.xlsx'));
  134. if exist(mp, 'file')
  135. masterPlateFile=mp;
  136. fprintf('Using master plate file: %s from internal logic\n', masterPlateFile);
  137. else
  138. fprintf('WARNING: Could not find MasterPlate file: %s\n', mp);
  139. fprintf('WARNING: Have you created a MasterPlate_ file in %s', easyResultsDir);
  140. end
  141. end
  142. if ~isempty(getenv('DRUG_MEDIA_FILE'))
  143. drugMediaFile=fullfile(getenv('DRUG_MEDIA_FILE'));
  144. fprintf('Using drug media file: %s from environment variable DRUG_MEDIA_FILE\n', drugMediaFile);
  145. else
  146. dm=fullfile(easyResultsDir, strcat('DrugMedia_', projectName,'.xlsx'));
  147. if exist(dm, 'file')
  148. drugMediaFile=dm;
  149. fprintf('Using drug media file: %s from internal logic\n', drugMediaFile);
  150. else
  151. fprintf('WARNING: Have you created a DrugMedia_ file in %s?\n', easyResultsDir);
  152. end
  153. end
  154. matDir=fullfile(easyResultsDir, 'matResults');
  155. matFile=fullfile(matDir,easyProjectName,'.mat');
  156. mpdmFile=fullfile(matDir,'MPDM.mat');
  157. printResultsDir=fullfile(easyResultsDir,'PrintResults');
  158. fotosResultsDir=fullfile(easyResultsDir,'Fotos');
  159. figsResultsDir=fullfile(easyResultsDir,'figs');
  160. pointMapsResultsDir=fullfile(easyResultsDir,'PTmats');
  161. pointMapsFile=fullfile(pointMapsResultsDir,'NImParameters.mat');
  162. oldPointMapsFile=fullfile(pointMapsResultsDir,'ImParameters.mat');
  163. searchRangeFile=fullfile(fotosResultsDir,'CSearchRange.mat');
  164. % Decent time to print some helpful vars
  165. if debug
  166. disp('Vars at end of main loop:')
  167. whos;
  168. end
  169. % This can be removed, I think it should add the previous search range?
  170. % Might be nice feature but can remove if it causes issues
  171. % We are using searchRangeNum to hold old CSrchRange value(s)
  172. if exist(searchRangeFile, 'file')
  173. searchRangeNum=load(searchRangeFile);
  174. end
  175. % Add easyDir to the MATLAB path
  176. % I have not idea if this is necessary or works but theoretically should
  177. % reduce directory scoping issues when calling scripts w/o a path
  178. addpath(easyDir);
  179. % GUI interface design
  180. gui_Singleton=1;
  181. gui_State=struct(...
  182. 'gui_Name', mfilename, ...
  183. 'gui_Singleton', gui_Singleton, ...
  184. 'gui_OpeningFcn', @EASYconsole_OpeningFcn, ...
  185. 'gui_OutputFcn', @EASYconsole_OutputFcn, ...
  186. 'gui_LayoutFcn', [] , ...
  187. 'gui_Callback', []);
  188. if nargin && ischar(varargin{1})
  189. gui_State.gui_Callback=str2func(varargin{1});
  190. end
  191. if nargout
  192. [varargout{1:nargout}]=gui_mainfcn(gui_State, varargin{:});
  193. else
  194. gui_mainfcn(gui_State, varargin{:});
  195. end
  196. end
  197. % GUI
  198. % Easyconcole_OpeningFcn executes just before the EASYconsole GUI is made visible.
  199. % This function has no output args, see OutputFcn.
  200. % hObject--handle to figure
  201. % eventdata reserved - to be defined in a future version of MATLAB
  202. % handles--structure with handles and user data (see GUIDATA)
  203. % varargin--input arguments to EASYconsole (see VARARGIN)
  204. function EASYconsole_OpeningFcn(hObject, ~, handles, varargin)
  205. global fhconsole
  206. global projectScansDir
  207. % Choose default command line output for EASYconsole
  208. handles.output=hObject;
  209. % Update handles structure
  210. guidata(hObject, handles);
  211. %Figure header, Toolbar, etc. Setup
  212. fhconsole=gcf;
  213. set(fhconsole,'Toolbar','none');
  214. fhconsole=gcf;
  215. % Pulled this out of the opening function
  216. % Seems better to wait until we have our vars set though?
  217. if exist('projectScansDir','var') && ~isempty(projectScansDir)
  218. set(fhconsole,'Name', sprintf('EASYconsole - %s', projectScansDir));
  219. else
  220. set(fhconsole,'Name','EASYconsole - No Active Experiment.')
  221. end
  222. end
  223. % EASYconsole output
  224. % Outputs from this function are returned to the command line.
  225. % varargout--cell array for returning output args (see VARARGOUT);
  226. % hObject--handle to figure
  227. % eventdata reserved - to be defined in a future version of MATLAB
  228. % handles--structure with handles and user data (see GUIDATA)
  229. function varargout = EASYconsole_OutputFcn(~, ~, handles)
  230. % Get default command line output from handles structure
  231. varargout{1}=handles.output;
  232. end
  233. % Console button interfaces
  234. % File Button Interface
  235. function FileMenu_Callback(~, ~, ~)
  236. % returnStartDir
  237. end
  238. % Load Experiment Button Interface
  239. function LoadExp_Callback(~, ~, ~)
  240. % returnStartDir
  241. end
  242. % New Experiment Button Interface
  243. function NewExpDat_Callback(~, ~, ~)
  244. global matDir
  245. global matFile
  246. global easyResultsDir
  247. global easyProjectName
  248. global fhconsole
  249. global scan
  250. global userName
  251. global todayStr
  252. % Create a new experiment
  253. try
  254. questdlg('Name the file and navigate to the directory with the image folders.','File Creation','OK', struct('Default','OK','Interpreter','tex'));
  255. [matfile,easyResultsDir]=uiputfile('.mat');
  256. inputFileName=strrep(inputFile,'.mat','');
  257. [~, projectName]=fileparts(easyResultsDir);
  258. % Set paths
  259. matDir=fullfile(easyResultsDir,'matResults');
  260. matFile=fullfile(matDir, projectName, '.mat');
  261. % Added for 'parfor global' to preallocate 'scan' structure
  262. nlist=dir(fullfile(projectScansDir,'*'));
  263. nnn=0;
  264. for n=1:size(nlist,1)
  265. if (~isempty(str2num(nlist(n).name)))
  266. nnn=nnn+1;
  267. PnumLst(nnn)= (str2num(nlist(n).name));
  268. sl(nnn,1)={(nlist(n).name)};
  269. end
  270. end
  271. scanSize=size(sl,1);
  272. scanMax=max(str2double(sl));
  273. clear scan;
  274. scan(scanMax)=struct(); % changed for parfor global 20_0118
  275. save(matFile,'scan')
  276. % create supporting dirs
  277. % this is also in the workflow script but here for standalone mode
  278. dirs={'PrintResults', 'CFfigs', 'Fotos'};
  279. for i=1:length(dirs)
  280. d=dirs{i};
  281. if ~exist(fullfile(easyResultsDir, d), 'dir')
  282. mkdir(fullfile(easyResultsDir, d));
  283. end
  284. end
  285. % templateDirs are stored in the easy template directory
  286. templates={'figs', 'PTmats'};
  287. for i=1:length(templates)
  288. d=dirs{i};
  289. if ~exist(fullfile(easyResultsDir, d), 'dir')
  290. copyfile((fullfile(easyDir,d)), (fullfile(easyResultsDir,d)));
  291. end
  292. end
  293. clear sbdg % reduce possible retention of a previous job sdbg
  294. sbdg= cell(1,scanMax);
  295. save((fullfile(easyResultsDir,'Fotos','Nbdg')),'sbdg');
  296. catch ME
  297. fprintf('ERROR: %s\n', ME.message);
  298. end
  299. % set the title for fhconsole depending on existence
  300. if exist('easyResultsDir','var') && ~isempty(easyResultsDir)
  301. set(fhconsole,'Name',sprintf('EASYconsole - %s', easyResultsDir));
  302. else
  303. set(fhconsole,'Name','EASYconsole - Master Plate directory not selected.');
  304. end
  305. end
  306. % Load a previous experiment
  307. function LoadDatFile_Callback(~, ~, ~)
  308. global matDir
  309. global matFile
  310. global projectName
  311. global easyResultsDir
  312. global easyProjectName
  313. global easyPath
  314. global fhconsole
  315. try
  316. questdlg('Load results .mat from ../out/project/','File Creation','OK', struct('Default','OK','Interpreter','tex'));
  317. [matDir,matFile]=uigetfile('.mat','Open Experiment folder and data storage .mat file name','MultiSelect','off');
  318. load(matFile);
  319. easyResultsDir=fullfile(matDir,'..');
  320. [~, projectName]=fileparts(easyResultsDir);
  321. projectScansDir=fullfile(easyResultsDir, '..', '..', 'scans', projectName);
  322. % TODO this is pretty hacky and needs something more explicit
  323. if isfolder(fullfile(matDir, '..','..','1')) % If Inovation Vrobot Then
  324. if load(pointMapsFile);
  325. elseif load(fullfile(easyPath,'NImParameters.mat')); % hardcoded default
  326. elseif load(fullfile(pointMapsResultsDir,'ImParameters.mat'));
  327. elseif load(fullfile(easyPath,'ImParameters.mat'));
  328. else
  329. disp("Could not load the ImParameters.mat file");
  330. end
  331. else
  332. disp('WARNING: cannot find project scans');
  333. end
  334. % Create supporting dirs
  335. dirs={'PrintResults', 'figs', 'CFfigs', 'PTmats', 'Fotos'};
  336. for i=1:length(dirs)
  337. d=dirs{i};
  338. if ~exist(fullfile(easyResultsDir, d), 'dir')
  339. mkdir(fullfile(easyResultsDir, d));
  340. end
  341. end
  342. catch
  343. end
  344. clear scan
  345. if exist('easyResultsDir','var') && ~isempty(easyResultsDir)
  346. fhconsole=gcf;
  347. set(fhconsole,'Name',sprintf('EASYconsole - %s', easyResultsDir));
  348. else
  349. set(fhconsole,'Name','EASYconsole - Exp. Analysis NOT selected.');
  350. end
  351. end
  352. % Callbacks
  353. % 'Run' in the dropdown menu
  354. function run_Callback(~, ~, ~)
  355. end
  356. function runPlateMapPintool_Callback(~, ~, ~)
  357. try
  358. NImapPT
  359. catch
  360. EASYconsole
  361. end
  362. end
  363. function NImCFcombo_Callback(~, ~, ~)
  364. try
  365. par4Gbl_Main8c
  366. EASYconsole
  367. catch
  368. EASYconsole
  369. end
  370. end
  371. function runPlateImAnal_Callback(~, ~, ~)
  372. try
  373. NImStartupOnly
  374. catch
  375. EASYconsole
  376. end
  377. end
  378. function PlateCFit_Callback(~, ~, ~)
  379. % global matFile % TODO BCR not sure if needed
  380. try
  381. NCstart
  382. catch
  383. EASYconsole
  384. end
  385. end
  386. function GenPrintouts_Callback(~, ~, ~)
  387. end
  388. function uploadExcelMP2DB_Callback(~, ~, ~)
  389. end
  390. function runDMPexcel_Callback(~, ~, ~)
  391. try
  392. DMPexcel2mat
  393. catch
  394. EASYconsole
  395. end
  396. end
  397. function runResults_DBcombo_Callback(~, ~, ~)
  398. try
  399. DgenResults
  400. catch ME
  401. fprintf('Error in DgenResults: %s\n', ME.message);
  402. EASYconsole
  403. end
  404. end
  405. function Tools_Callback(~, ~, ~)
  406. end
  407. function runOverlayPlots_Callback(~, ~, ~)
  408. try
  409. DoverlayPlots2
  410. EASYconsole
  411. catch
  412. EASYconsole
  413. end
  414. end
  415. function runFotoStrip_Callback(~, ~, ~)
  416. try
  417. F_NImStartup_CentCir
  418. EASYconsole
  419. catch
  420. EASYconsole
  421. end
  422. end
  423. function runDisplayFig_Callback(~, ~, ~)
  424. try
  425. UfigDisplay
  426. catch
  427. EASYconsole
  428. end
  429. end
  430. function runViewParameters_Callback(~, ~, ~)
  431. try
  432. catch
  433. EASYconsole
  434. end
  435. end
  436. function QkviewN_Callback(~, ~, ~)
  437. try
  438. QkviewImages
  439. catch
  440. EASYconsole
  441. end
  442. end
  443. function CFdisplay_Callback(~, ~, ~)
  444. try
  445. NCsingleDisplay
  446. EASYconsole
  447. catch
  448. EASYconsole
  449. end
  450. end