diff --git a/MonkeyLogic/initio.m b/MonkeyLogic/initio.m index 1bd5a30..9c7a75e 100644 --- a/MonkeyLogic/initio.m +++ b/MonkeyLogic/initio.m @@ -8,7 +8,11 @@ % Last modified 8/11/08 -WA (to make certain analog-input objects use DMA) % Last modified 11/17/15 -ER (Added DigitalInputStream for touchscreens and other future devices) -disp('<<< MonkeyLogic >>> Initializing I/O') +logger = log4m.getLogger('log.txt'); +logger.setCommandWindowLevel(logger.ALL); +logger.setLogLevel(logger.ALL); + +logger.info('initio.m', '<<< MonkeyLogic >>> Initializing I/O'); %for manual editing: configIO.AI.BufferingConfig = [16 1024]; %[1 2000]; @@ -56,7 +60,7 @@ elseif strcmp(fnfrag, 'TTL'), REQSYS.(fn) = {'DigitalIO'}; else - fprintf('Warning: Unable to test IO type %s for subsystem validity using "initio.m"', fn); + logger.info('initio.m', sprintf('Warning: Unable to test IO type %s for subsystem validity using "initio.m"', fn)); end end @@ -72,7 +76,7 @@ DaqError = cell(2, 1); DaqError{1} = '*** Error: Non-permitted I/O mapping ***'; DaqError{2} = sprintf('Allowed Type for %s: %s %s ', fn, reqsys{:}); - fprintf('*** Error: Non-permitted I/O mapping for %s ***', fn); + logger.info('initio.m', sprintf('*** Error: Non-permitted I/O mapping for %s ***', fn)); return end end @@ -90,7 +94,7 @@ end if length(unique(aicstr)) > 1, DaqError{1} = '*** Error: All analog inputs must be on the same board ***'; - disp(DaqError{1}) + logger.info('initio.m', DaqError{1}); return end @@ -108,7 +112,7 @@ end if count > 1 && length(unique(butsys)) > 1, DaqError{1} = '*** Error: Button inputs must be either all analog or all digital ***'; - disp(DaqError{1}) + logger.info('initio.m', DaqError{1}); end DAQ.AnalogInput = []; @@ -131,7 +135,7 @@ if EyeXpresent || EyeYpresent, if numfieldsEyeX ~= numfieldsEyeY, DaqError{1} = 'I/O Error: Must define 0 or 2 eye signal inputs'; - disp('I/O Error: Must define 0 or 2 eye signal inputs') + logger.info('initio.m', 'I/O Error: Must define 0 or 2 eye signal inputs'); return end end @@ -145,7 +149,7 @@ if JoyXpresent || JoyYpresent, if numfieldsJoyX ~= numfieldsJoyY, DaqError{1} = 'I/O Error: Must define 0 or 2 joystick inputs'; - disp('I/O Error: Must define 0 or 2 joystick inputs') + logger.info('initio.m', 'I/O Error: Must define 0 or 2 joystick inputs'); return end end @@ -159,7 +163,7 @@ if TouchXpresent || TouchYpresent, if numfieldsTouchX ~= numfieldsTouchY, DaqError{1} = 'I/O Error: Must define 0 or 2 touchscreen inputs'; - disp('I/O Error: Must define 0 or 2 touchscreen inputs') + logger.info('initio.m', 'I/O Error: Must define 0 or 2 touchscreen inputs'); return end end @@ -173,7 +177,7 @@ if MouseXpresent || MouseYpresent, if numfieldsMouseX ~= numfieldsMouseY, DaqError{1} = 'I/O Error: Must define 0 or 2 mouse inputs'; - disp('I/O Error: Must define 0 or 2 mouse inputs') + logger.info('initio.m', 'I/O Error: Must define 0 or 2 mouse inputs'); return end end @@ -204,7 +208,7 @@ [DAQ.AnalogInput DaqError] = init_ai(IO.(signame).Constructor, configIO); if ~isempty(DaqError), DaqError{1} = sprintf('%s: %s', signame, DaqError{1}); - disp(DaqError{1}) + logger.info('initio.m', DaqError{1}); daqreset; return end @@ -277,8 +281,8 @@ elseif ~any(board2) && configIO.AI.AnalogInputDuplication, h = findobj('tag', 'monkeylogicmainmenu'); if ~isempty(h) && strcmpi(get(findobj(h, 'tag', 'aiduplication'), 'enable'), 'on'), - fprintf('Warning: No duplicate boards found to assign %s...', signame); - disp('... must sample and store data from the same DAQ board (suboptimal performance will result)'); + logger.info('initio.m', sprintf('Warning: No duplicate boards found to assign %s...', signame)); + logger.info('initio.m', '... must sample and store data from the same DAQ board (suboptimal performance will result)'); end end @@ -329,19 +333,19 @@ if ~isfield(IO.CodesDigOut, 'Constructor'), DaqError{1} = '*** No digital lines assigned for event marker output ***'; - disp(DaqError{1}); + logger.info('initio.m', DaqError{1}); daqreset; return end if ~isfield(IO.DigCodesStrobeBit, 'Constructor'), DaqError{1} = '*** Must assign a strobe bit for behavioral code digital output ***'; - disp(DaqError{1}); + logger.info('initio.m', DaqError{1}); daqreset; return end if ~strcmp(IO.DigCodesStrobeBit.Constructor, IO.CodesDigOut.Constructor), DaqError{1} = '*** Strobe bit line must be on the same board & subsystem as the behavioral code data lines ***'; - disp(DaqError{1}); + logger.info('initio.m', DaqError{1}); daqreset; return end @@ -360,7 +364,7 @@ DAQ.BehavioralCodes.DataBits = addline(DAQ.BehavioralCodes.DIO, hwlines, 'out', 'BehaviorCodes'); catch DaqError{1} = '*** Unable to assign output digital lines for Behavioral Codes ***'; - disp(DaqError{1}); + logger.info('initio.m', DaqError{1}); rethrow(lasterror); daqreset; return @@ -372,7 +376,7 @@ DAQ.BehavioralCodes.StrobeBit = addline(DAQ.BehavioralCodes.DIO, hwline, portnumber, 'out', 'StrobeBit'); catch DaqError{1} = sprintf('*** Unable to assign line %i on port %i as a digital strobe output bit ***', hwline, portnumber); - disp(DaqError{1}); + logger.info('initio.m', DaqError{1}); daqreset; return end diff --git a/MonkeyLogic/initstim.m b/MonkeyLogic/initstim.m index a943952..0ee4946 100644 --- a/MonkeyLogic/initstim.m +++ b/MonkeyLogic/initstim.m @@ -1,9 +1,12 @@ function C = initstim(fname, ScreenInfo) % Created 8/23/08 -WA +logger = log4m.getLogger('log.txt'); +logger.setCommandWindowLevel(logger.ALL); +logger.setLogLevel(logger.ALL); P = getpref('MonkeyLogic'); sourcefile = [P.Directories.BaseDirectory fname]; -fprintf('<<< MonkeyLogic >>> Initstim.m is looking for %s\r\n', sourcefile); +logger.info('initstim.m', sprintf('<<< MonkeyLogic >>> Looking for %s', sourcefile)); [pname fname ext] = fileparts(sourcefile); processedfile = [pname filesep fname '_preprocessed.mat']; if strcmpi(ext, '.avi'), diff --git a/MonkeyLogic/ioscan.m b/MonkeyLogic/ioscan.m index 28e9165..66a4aa9 100644 --- a/MonkeyLogic/ioscan.m +++ b/MonkeyLogic/ioscan.m @@ -4,10 +4,14 @@ % Modified 2/1/07 (bug in digitalio assignments fixed) --WA % Modified 1/4/08 (improved error handling) --WA -disp('<<< MonkeyLogic >>> Gathering I/O board info (running ioscan.m)...') +logger = log4m.getLogger('log.txt'); +logger.setCommandWindowLevel(logger.ALL); +logger.setLogLevel(logger.ALL); + +logger.info('ioscan.m', '<<< MonkeyLogic >>> Gathering I/O board info (running ioscan.m)...'); hwinfo = daqhwinfo; -fprintf('<<< MonkeyLogic >>> DAQ Driver Version: %s %s\n', daq.getVendors().FullName, daq.getVendors().DriverVersion); -fprintf('<<< MonkeyLogic >>> DAQ Toolbox Version: %s %s\n', hwinfo.ToolboxName, hwinfo.ToolboxVersion); +logger.info('ioscan.m', sprintf('<<< MonkeyLogic >>> DAQ Driver Version: %s %s', daq.getVendors().FullName, daq.getVendors().DriverVersion)); +logger.info('ioscan.m', sprintf('<<< MonkeyLogic >>> DAQ Toolbox Version: %s %s', hwinfo.ToolboxName, hwinfo.ToolboxVersion)); %insert an additional adapter numFound = length(hwinfo.InstalledAdaptors); @@ -116,9 +120,9 @@ end end -fprintf('<<< MonkeyLogic >>> Found %i I/O adaptors:\n', length(adaptors)); +logger.info('ioscan.m', sprintf('<<< MonkeyLogic >>> Found %i I/O adaptors:', length(adaptors))); for i = 1:length(adaptors), - fprintf('... %i) %s\n', i, adaptors{i}); + logger.info('ioscan.m', sprintf('... %i) %s', i, adaptors{i})); end AdaptorInfo = AdaptorInfo(1:totalboards); diff --git a/MonkeyLogic/load_conditions.m b/MonkeyLogic/load_conditions.m index 70ae902..f8a76ed 100644 --- a/MonkeyLogic/load_conditions.m +++ b/MonkeyLogic/load_conditions.m @@ -17,6 +17,10 @@ % Modified 8/19/08 -WA (to handle non-integer RelativeFrequency values) % +logger = log4m.getLogger('log.txt'); +logger.setCommandWindowLevel(logger.ALL); +logger.setLogLevel(logger.ALL); + cerror = ''; Conditions = struct; @@ -50,7 +54,7 @@ end fid = fopen(txtfile); -disp(sprintf('<<< MonkeyLogic >>> Loading conditions file', txtfile)); +logger.info('loadconditions.m', sprintf('<<< MonkeyLogic >>> Loading conditions file %s', txtfile)); if fid < 1, cerror = 'Unable to open Conditions file'; return @@ -91,7 +95,7 @@ i=i+1; if i > length(h)+5, cerror = 'Unable to parse conditions file header.'; - fprintf('Valid columns are "Condition", "Frequency", "Block", "Timing File", "Info", and "TaskObject#1" through TaskObject#N".\n'); + logger.info('loadconditions.m', sprintf('Valid columns are "Condition", "Frequency", "Block", "Timing File", "Info", and "TaskObject#1" through TaskObject#N".')); return end end diff --git a/MonkeyLogic/log4m.m b/MonkeyLogic/log4m.m new file mode 100644 index 0000000..7110be3 --- /dev/null +++ b/MonkeyLogic/log4m.m @@ -0,0 +1,269 @@ +classdef log4m < handle + %LOG4M This is a simple logger based on the idea of the popular log4j. + % + % Description: Log4m is designed to be relatively fast and very easy to + % use. It has been designed to work well in a matlab environment. + % Please contact me (info below) with any questions or suggestions! + % + % + % Author: + % Luke Winslow + % Heavily modified version of 'log4matlab' which can be found here: + % http://www.mathworks.com/matlabcentral/fileexchange/33532-log4matlab + % + + properties (Constant) + ALL = 0; + TRACE = 1; + DEBUG = 2; + INFO = 3; + WARN = 4; + ERROR = 5; + FATAL = 6; + OFF = 7; + end + + properties(Access = protected) + logger; + lFile; + end + + properties(SetAccess = protected) + fullpath = 'log4m.log'; %Default file + commandWindowLevel = log4m.ALL; + logLevel = log4m.INFO; + end + + methods (Static) + function obj = getLogger( logPath ) + %GETLOGGER Returns instance unique logger object. + % PARAMS: + % logPath - Relative or absolute path to desired logfile. + % OUTPUT: + % obj - Reference to signular logger object. + % + + if(nargin == 0) + logPath = 'log4m.log'; + elseif(nargin > 1) + error('getLogger only accepts one parameter input'); + end + + persistent localObj; + if isempty(localObj) || ~isvalid(localObj) + localObj = log4m(logPath); + end + obj = localObj; + end + + function testSpeed( logPath ) + %TESTSPEED Gives a brief idea of the time required to log. + % + % Description: One major concern with logging is the + % performance hit an application takes when heavy logging is + % introduced. This function does a quick speed test to give + % the user an idea of how various types of logging will + % perform on their system. + % + + L = log4m.getLogger(logPath); + + + disp('1e5 logs when logging only to command window'); + + L.setCommandWindowLevel(L.TRACE); + L.setLogLevel(L.OFF); + tic; + for i=1:1e5 + L.trace('log4mTest','test'); + end + + disp('1e5 logs when logging only to command window'); + toc; + + disp('1e6 logs when logging is off'); + + L.setCommandWindowLevel(L.OFF); + L.setLogLevel(L.OFF); + tic; + for i=1:1e6 + L.trace('log4mTest','test'); + end + toc; + + disp('1e4 logs when logging to file'); + + L.setCommandWindowLevel(L.OFF); + L.setLogLevel(L.TRACE); + tic; + for i=1:1e4 + L.trace('log4mTest','test'); + end + toc; + + end + end + + +%% Public Methods Section %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + methods + function setFilename(self,logPath) + %SETFILENAME Change the location of the text log file. + % + % PARAMETERS: + % logPath - Name or full path of desired logfile + % + + [fid,message] = fopen(logPath, 'a'); + + if(fid < 0) + error(['Problem with supplied logfile path: ' message]); + end + fclose(fid); + + self.fullpath = logPath; + end + + + function setCommandWindowLevel(self,loggerIdentifier) + self.commandWindowLevel = loggerIdentifier; + end + + + function setLogLevel(self,logLevel) + self.logLevel = logLevel; + end + + +%% The public Logging methods %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + function trace(self, funcName, message) + %TRACE Log a message with the TRACE level + % + % PARAMETERS: + % funcName - Name of the function or location from which + % message is coming. + % message - Text of message to log. + % + self.writeLog(self.TRACE,funcName,message); + end + + function debug(self, funcName, message) + %TRACE Log a message with the DEBUG level + % + % PARAMETERS: + % funcName - Name of the function or location from which + % message is coming. + % message - Text of message to log. + % + self.writeLog(self.DEBUG,funcName,message); + end + + + function info(self, funcName, message) + %TRACE Log a message with the INFO level + % + % PARAMETERS: + % funcName - Name of the function or location from which + % message is coming. + % message - Text of message to log. + % + self.writeLog(self.INFO,funcName,message); + end + + + function warn(self, funcName, message) + %TRACE Log a message with the WARN level + % + % PARAMETERS: + % funcName - Name of the function or location from which + % message is coming. + % message - Text of message to log. + % + self.writeLog(self.WARN,funcName,message); + end + + + function error(self, funcName, message) + %TRACE Log a message with the ERROR level + % + % PARAMETERS: + % funcName - Name of the function or location from which + % message is coming. + % message - Text of message to log. + % + self.writeLog(self.ERROR,funcName,message); + end + + + function fatal(self, funcName, message) + %TRACE Log a message with the FATAL level + % + % PARAMETERS: + % funcName - Name of the function or location from which + % message is coming. + % message - Text of message to log. + % + self.writeLog(self.FATAL,funcName,message); + end + + end + +%% Private Methods %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Unless you're modifying this, these should be of little concern to you. + methods (Access = private) + + function self = log4m(fullpath_passed) + + if(nargin > 0) + path = fullpath_passed; + end + self.setFilename(path); + end + +%% WriteToFile + function writeLog(self,level,scriptName,message) + + % If necessary write to command window + if( self.commandWindowLevel <= level ) + fprintf('%s:%s\n', scriptName, message); + end + + %If currently set log level is too high, just skip this log + if(self.logLevel > level) + return; + end + + % set up our level string + switch level + case{self.TRACE} + levelStr = 'TRACE'; + case{self.DEBUG} + levelStr = 'DEBUG'; + case{self.INFO} + levelStr = 'INFO'; + case{self.WARN} + levelStr = 'WARN'; + case{self.ERROR} + levelStr = 'ERROR'; + case{self.FATAL} + levelStr = 'FATAL'; + otherwise + levelStr = 'UNKNOWN'; + end + + % Append new log to log file + try + fid = fopen(self.fullpath,'a'); + fprintf(fid,'%s %s %s - %s\r\n' ... + , datestr(now,'yyyy-mm-dd HH:MM:SS,FFF') ... + , levelStr ... + , scriptName ... % Have left this one with the '.' if it is passed + , message); + fclose(fid); + catch ME_1 + display(ME_1); + end + end + end + +end diff --git a/MonkeyLogic/mllog.m b/MonkeyLogic/mllog.m deleted file mode 100644 index b4d3105..0000000 --- a/MonkeyLogic/mllog.m +++ /dev/null @@ -1,65 +0,0 @@ -% mllog will write a message to a log file and simultaneously output the same message to the console -% -% February 5, 2016 Created by Edward Ryklin (edward@ryklinsoftware.com) -% - -classdef mllog < handle - - properties %(Access = protected) - fid = -1; - numLines = -1; - end % end of properties - - methods ( Access = 'public' ) - - function obj = mllog(fileName) - obj.openLogFile(fileName); - end - - function delete(obj) - obj.closeLogFile(); - end - - function openLogFile(obj, fileName) - - if (obj.fid > 0) - obj.closeLogFile(); - end - - dirs = getpref('MonkeyLogic', 'Directories'); - logFileName = strcat(dirs.RunTimeDirectory, fileName); - - obj.fid = fopen(logFileName, 'w'); - obj.numLines = 0; - if (obj.fid) - obj.logMessage(sprintf('<<< %s.m >>> Created a new log file %s', class(obj), datestr(now)) ); - else - obj.logMessage(sprintf('<<< %s.m >>> Did not create a log file!', class(obj) )); - end - end - - function logMessage(obj, message) - - disp(message); % send message to Matlab Console if it exists - - obj.numLines = obj.numLines + 1; - if (obj.fid > 0) % send message to file if it exists - message = sprintf('%i %s\r\n', obj.numLines, message); - fprintf(obj.fid, message); - else - fprintf('<<< %s.m >>> Did not log that message to file!\n', class(obj)); - end - end - - function closeLogFile(obj) - if (obj.fid > 0) - obj.logMessage(sprintf('<<< %s.m >>> Closing log file %s', class(obj), datestr(now))); - fclose(obj.fid); - end - obj.fid = 0; - end - - end % end of methods - -end % end of classdef mllog - diff --git a/MonkeyLogic/mlmenu.m b/MonkeyLogic/mlmenu.m index 6af68ab..bc376c6 100644 --- a/MonkeyLogic/mlmenu.m +++ b/MonkeyLogic/mlmenu.m @@ -13,8 +13,11 @@ function mlmenu(varargin) % Modified 10/01/15 -ER (added touchscreen/mouse controllers) lastupdate = 'February 2016'; -currentversion = '02-12-2016 build 1.2.36'; -logger = mllog('mlmenu.log'); +currentversion = '02-25-2016 build 1.2.37'; + +logger = log4m.getLogger('log.txt'); +logger.setCommandWindowLevel(logger.ALL); +logger.setLogLevel(logger.ALL); mlf = findobj('tag', 'monkeylogicmainmenu'); if ~isempty(mlf) && isempty(gcbo), @@ -81,7 +84,7 @@ function mlmenu(varargin) if isempty(mlf), fprintf('\r\n\r\n\r\n'); - logger.logMessage(sprintf('<<< MonkeyLogic >>> Revision : %s', currentversion)) + logger.info('mlmenu.m', sprintf('<<< MonkeyLogic >>> Revision : %s', currentversion)) chknewupdates(lastupdate); envOS = getenv('OS'); envCN = getenv('COMPUTERNAME'); @@ -92,29 +95,29 @@ function mlmenu(varargin) envPRC = getenv('CPU'); end if ~isempty(envOS), - logger.logMessage(sprintf('<<< MonkeyLogic >>> Operating System: %s...', envOS)) + logger.info('mlmenu.m', sprintf('<<< MonkeyLogic >>> Operating System: %s...', envOS)) end if usejava('jvm'), - logger.logMessage('<<< MonkeyLogic >>> *** JAVA Virtual Machine is Running ***'); + logger.info('mlmenu.m', '<<< MonkeyLogic >>> *** JAVA Virtual Machine is Running ***'); end if ~isempty(envCN), - logger.logMessage(sprintf('<<< MonkeyLogic >>> Computer Name: %s...', envCN)) + logger.info('mlmenu.m', sprintf('<<< MonkeyLogic >>> Computer Name: %s...', envCN)) end if ~isempty(envUSER), - logger.logMessage(sprintf('<<< MonkeyLogic >>> Logged in as "%s"...', envUSER)) + logger.info('mlmenu.m', sprintf('<<< MonkeyLogic >>> Logged in as "%s"...', envUSER)) else envUSER = 'Investigator'; end if ~isempty(envNOP), envNOP = str2double(envNOP); if envNOP > 1, - logger.logMessage(sprintf('<<< MonkeyLogic >>> Detected %i "%s" processors...', envNOP, envPRC)) + logger.info('mlmenu.m', sprintf('<<< MonkeyLogic >>> Detected %i "%s" processors...', envNOP, envPRC)) else - logger.logMessage(sprintf('<<< MonkeyLogic >>> Detected only %i "%s" processor...', envNOP, envPRC)) + logger.info('mlmenu.m', sprintf('<<< MonkeyLogic >>> Detected only %i "%s" processor...', envNOP, envPRC)) end end envMVER = version; - logger.logMessage(sprintf('<<< MonkeyLogic >>> Matlab version: %s...', envMVER)) + logger.info('mlmenu.m', sprintf('<<< MonkeyLogic >>> Matlab version: %s...', envMVER)) numloops = 1000; t = zeros(numloops, 1); tic; @@ -122,8 +125,8 @@ function mlmenu(varargin) t(i) = toc; end mrate = 1/(mean(diff(t))*1000); - logger.logMessage(sprintf('<<< MonkeyLogic >>> Approximate Matlab cycle rate is %4.0f kHz', mrate)) - logger.logMessage('<<< MonkeyLogic >>> Launching Menu...') + logger.info('mlmenu.m', sprintf('<<< MonkeyLogic >>> Approximate Matlab cycle rate is %4.0f kHz', mrate)) + logger.info('mlmenu.m', '<<< MonkeyLogic >>> Launching Menu...') figure; figbg = [.65 .70 .80]; bgpurple = [.8 .76 .82]; @@ -133,7 +136,7 @@ function mlmenu(varargin) scrnx = scrnsz(3); scrny = scrnsz(4); if scrnx < 1280 || scrny < 768, - logger.logMessage('<<< MonkeyLogic >>> Warning: A primary-monitor resolution of at least 1280 x 768 is recommended...') + logger.info('mlmenu.m', '<<< MonkeyLogic >>> Warning: A primary-monitor resolution of at least 1280 x 768 is recommended...') end fxpos = 0.5 * (scrnx - figx); fypos = 0.5 * (scrny - figy); @@ -148,7 +151,7 @@ function mlmenu(varargin) set(gcf, 'closerequestfcn', 'mlmenu; delete(get(0, ''userdata'')); set(0, ''userdata'', ''''); disp(''Closed MonkeyLogic.'')'); mlvideo('mlinit'); - logger.logMessage('<<< MonkeyLogic >>> Initialized ML Video Graphics interface...') + logger.info('mlmenu.m', '<<< MonkeyLogic >>> Initialized ML Video Graphics interface...') ybase = 550; uicontrol('style', 'frame', 'position', [10 ybase+22 280 80], 'backgroundcolor', 0.85*figbg, 'foregroundcolor', 0.6*figbg); @@ -331,15 +334,15 @@ function mlmenu(varargin) uicontrol('style', 'frame', 'position', [559 ybase+27 157 50], 'backgroundcolor', figbg, 'foregroundcolor', [.5 .5 .5]); pic = 'runbuttondim.jpg'; uicontrol('style', 'pushbutton', 'position', [560 ybase+28 155 48], 'string', '', 'callback', 'mlmenu', 'tag', 'runbutton', 'backgroundcolor', [0.9 0.6 0.6], 'enable', 'inactive', 'cdata', imread(pic)); - logger.logMessage('<<< MonkeyLogic >>> Initialized Task Menu...') + logger.info('mlmenu.m', '<<< MonkeyLogic >>> Initialized Task Menu...') % VIDEO ###################################### mlvideo('init'); numdevices = mlvideo('devices'); if numdevices > 1, - logger.logMessage(sprintf('<<< MonkeyLogic >>> Found %i video devices...', numdevices)) + logger.info('mlmenu.m', sprintf('<<< MonkeyLogic >>> Found %i video devices...', numdevices)) else - logger.logMessage('<<< MonkeyLogic >>> Warning: Found only 1 video device...') + logger.info('mlmenu.m', '<<< MonkeyLogic >>> Warning: Found only 1 video device...') end mlvideo('release'); @@ -392,7 +395,7 @@ function mlmenu(varargin) uicontrol('style', 'edit', 'position', [xbase+45 ybase-22 33 20], 'string', num2str(defaultbgcolor(1)), 'userdata', defaultbgcolor(1), 'backgroundcolor', [1 1 1], 'tag', 'bgred', 'callback', 'mlmenu'); uicontrol('style', 'edit', 'position', [xbase+78 ybase-22 33 20], 'string', num2str(defaultbgcolor(2)), 'userdata', defaultbgcolor(2), 'backgroundcolor', [1 1 1], 'tag', 'bggreen', 'callback', 'mlmenu'); uicontrol('style', 'edit', 'position', [xbase+111 ybase-22 33 20], 'string', num2str(defaultbgcolor(3)), 'userdata', defaultbgcolor(3), 'backgroundcolor', [1 1 1], 'tag', 'bgblue', 'callback', 'mlmenu'); - logger.logMessage('<<< MonkeyLogic >>> Initialized Video Menu...') + logger.info('mlmenu.m', '<<< MonkeyLogic >>> Initialized Video Menu...') % Control Screen Options ###################################### ybase = 73; @@ -476,7 +479,7 @@ function mlmenu(varargin) set(h, 'color', 0.5*defaultjoycolor, 'linewidth', 3, 'markersize', 35, 'tag', 'sample_joy_target'); h = plot(xpos, 0, '.'); set(h, 'color', defaultjoycolor, 'markersize', defaultjoysize, 'tag', 'sample_joy_trace'); - logger.logMessage('<<< MonkeyLogic >>> Initialized Control-Screen Menu...') + logger.info('mlmenu.m', '<<< MonkeyLogic >>> Initialized Control-Screen Menu...') % INPUT / OUTPUT ###################################### AdaptorInfo = ioscan(); @@ -538,9 +541,9 @@ function mlmenu(varargin) end if ~any(duplicateboard), set(findobj(gcf, 'tag', 'aiduplication'), 'enable', 'off'); - logger.logMessage('<<< MonkeyLogic >>> Warning: no duplicate DAQ boards found for Analog Input duplication...') + logger.info('mlmenu.m', '<<< MonkeyLogic >>> Warning: no duplicate DAQ boards found for Analog Input duplication...') else - logger.logMessage('<<< MonkeyLogic >>> Detected duplicate DAQ boards: enabling A-I duplication...') + logger.info('mlmenu.m', '<<< MonkeyLogic >>> Detected duplicate DAQ boards: enabling A-I duplication...') end uicontrol('style', 'pushbutton', 'position', [xbase+299 ybase-138 118 22], 'string', 'Test Analog Inputs', 'tag', 'aitest', 'enable', 'off', 'callback', 'mlmenu'); @@ -564,7 +567,7 @@ function mlmenu(varargin) codestr = '???'; codesfile = 'n/a'; enablestr = 'off'; - logger.logMessage('<<< MonkeyLogic >>> Warning: No behavioral codes description file found...') + logger.info('mlmenu.m', '<<< MonkeyLogic >>> Warning: No behavioral codes description file found...') else enablestr = 'on'; codestr = defaultcodesfile; @@ -620,7 +623,7 @@ function mlmenu(varargin) uicontrol('style', 'pushbutton', 'position', [xbase+15 ybase-70 203 20], 'string', 'n/a', 'tag', 'au_userdefinedcritfunction', 'enable', 'off', 'backgroundcolor', [1 1 1], 'callback', 'mlmenu', 'userdata', ''); uicontrol('style', 'pushbutton', 'position', [xbase+15 ybase-103 203 20], 'string', 'n/a', 'tag', 'au_function', 'enable', 'off', 'backgroundcolor', [1 1 1], 'callback', 'mlmenu', 'userdata', ''); - logger.logMessage('<<< MonkeyLogic >>> Initialized I/O Menu...') + logger.info('mlmenu.m', '<<< MonkeyLogic >>> Initialized I/O Menu...') %%% PULL-DOWN MENUS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% filemenu = uimenu('label', 'File'); @@ -665,16 +668,16 @@ function mlmenu(varargin) uimenu(helpmenu, 'label', 'Online Help', 'callback', 'web(''http://www.monkeylogic.net'', ''-browser'')', 'accelerator', 'h'); uimenu(helpmenu, 'label', 'About...', 'tag', 'menubar_aboutbutton', 'callback', 'mlmenu'); if usejava('jvm'), - logger.logMessage('<<< MonkeyLogic >>> Initialized drop-down menus...') + logger.info('mlmenu.m', '<<< MonkeyLogic >>> Initialized drop-down menus...') end if exist(cfgfile, 'file'), - loadcfg(cfgfile, logger); + loadcfg(cfgfile); update_minicontrolscreen; else % if doesn't exist, create default config file... savecfg; end - logger.logMessage('<<< MonkeyLogic >>> Ready.') + logger.info('mlmenu.m', '<<< MonkeyLogic >>> Ready.') elseif ismember(gcbo, get(findobj('tag', 'monkeylogicmainmenu'), 'children')) || reloadcondfile || ismember(get(gcbo, 'parent'), get(findobj('tag', 'monkeylogicmainmenu'), 'children')), @@ -795,7 +798,7 @@ function mlmenu(varargin) %update settings if config file already exists... cfgfile = [MLPrefs.Directories.ExperimentDirectory cfgfile]; if exist(cfgfile, 'file'), - loadcfg(cfgfile, logger); + loadcfg(cfgfile); end set(findobj(gcf, 'tag', 'savebutton'), 'enable', 'off'); set(findobj(gcf, 'tag', 'menubar_savebutton'), 'enable', 'off'); @@ -842,7 +845,7 @@ function mlmenu(varargin) f = wavread('science.wav'); sound(f, 48000); catch - logger.logMessage(''); + logger.info('mlmenu.m', ''); end case 'editconds', @@ -870,7 +873,7 @@ function mlmenu(varargin) [filename pathname] = uigetfile([MLPrefs.Directories.ExperimentDirectory '*_cfg.mat']); if filename ~= 0, - loadcfg([pathname filename], logger); + loadcfg([pathname filename]); end rbh = findobj(gcf, 'tag', 'runblocks'); blocklist = get(rbh, 'userdata'); @@ -1275,7 +1278,7 @@ function mlmenu(varargin) end cfgname = get(findobj(gcf, 'tag', 'configfilename'), 'string'); - loadcfg([MLPrefs.Directories.ExperimentDirectory cfgname], logger); + loadcfg([MLPrefs.Directories.ExperimentDirectory cfgname]); if strcmpi(p, 'off'), mlmessage('Loaded personal hardware settings.'); @@ -1927,7 +1930,7 @@ function mlmenu(varargin) case 'videotest', - logger.logMessage('<<< MonkeyLogic >>> Starting video test'); + logger.info('mlmenu.m', '<<< MonkeyLogic >>> Starting video test'); mlmessage('Initializing video...'); drawnow; @@ -3619,7 +3622,11 @@ function clean_borders(fx, fy, fw, fh, fbg) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -function loadcfg(cfgfile, logger) +function loadcfg(cfgfile) + +logger = log4m.getLogger('log.txt'); +logger.setCommandWindowLevel(logger.ALL); +logger.setLogLevel(logger.ALL); load(cfgfile); @@ -3866,7 +3873,7 @@ function loadcfg(cfgfile, logger) numdevices = length(get(findobj(gcf, 'tag', 'videodevice'), 'string')); if MLConfig.VideoDevice > numdevices, - logger.logMessage(sprintf('*** WARNING: Assigned video device (#%i) not available ***', MLConfig.VideoDevice)) + logger.info('mlmenu.m', sprintf('*** WARNING: Assigned video device (#%i) not available ***', MLConfig.VideoDevice)) MLConfig.VideoDevice = numdevices; end set(findobj(gcf, 'tag', 'videodevice'), 'value', MLConfig.VideoDevice); @@ -3983,7 +3990,7 @@ function loadcfg(cfgfile, logger) catch str = sprintf('*** WARNING: Assigned adaptor for %s not currently available ***', fn{i}); mlmessage(str); - logger.logMessage(str) + logger.info('mlmenu.m', str) end end end @@ -4217,7 +4224,7 @@ function savecfg(varargin) else cfgfile = [MLPrefs.Directories.BaseDirectory 'default_cfg.mat']; end - logger.logMessage('... Saving new default configuration file ...') + logger.info('mlmenu.m', '... Saving new default configuration file ...') save(cfgfile, 'MLConfig'); end setpref('MonkeyLogic', 'Directories', MLPrefs.Directories); @@ -4258,7 +4265,7 @@ function chknewupdates(lastupdate) setpref('MonkeyLogic', 'LastUpdateCheck', todaynum); end catch ME %likely no network... - logger.logMessage(sprintf('>>> Unable to check for MonkeyLogic updates (%s) <<<', ME.identifier)) + logger.info('mlmenu.m', sprintf('>>> Unable to check for MonkeyLogic updates (%s) <<<', ME.identifier)) end diff --git a/MonkeyLogic/mlvideo.m b/MonkeyLogic/mlvideo.m index c13cf4a..80b1851 100644 --- a/MonkeyLogic/mlvideo.m +++ b/MonkeyLogic/mlvideo.m @@ -45,6 +45,10 @@ global y_touch; global screen_ppd; +logger = log4m.getLogger('log.txt'); +logger.setCommandWindowLevel(logger.ALL); +logger.setLogLevel(logger.ALL); + switch fxn case 'waitflip', @@ -94,8 +98,7 @@ end case 'init', - - disp('<<< MonkeyLogic >>> Initialized XGL - DirectX 9 fullscreen graphics layer for Matlab...') + logger.info('mlvideo.m', '<<< MonkeyLogic >>> Initialized XGL - DirectX 9 fullscreen graphics layer for Matlab...'); xglrelease; xglinit; diff --git a/MonkeyLogic/monkeylogic.m b/MonkeyLogic/monkeylogic.m index 2c411a5..bb40fb7 100644 --- a/MonkeyLogic/monkeylogic.m +++ b/MonkeyLogic/monkeylogic.m @@ -40,8 +40,11 @@ end return end -logger = mllog('monkeylogic.log'); -logger.logMessage(sprintf('\r\r\r')) +logger = log4m.getLogger('log.txt'); +logger.setCommandWindowLevel(logger.ALL); +logger.setLogLevel(logger.ALL); + +logger.info('monkeylogic.m', sprintf('\r\r\r')); if length(varargin) > 2, thisisonlyatest = varargin{3}; @@ -154,7 +157,7 @@ MLConfig.ComputerName = lower(getenv('COMPUTERNAME')); MLHELPER_OFF = MLConfig.MLHelperOff; -%logger.logMessage(sprintf('Setting MLHELPER_OFF to %i', MLHELPER_OFF)); +%logger.info('monkeylogic.m', sprintf('Setting MLHELPER_OFF to %i', MLHELPER_OFF)); % Read conditions file Conditions_temp = load_conditions(condfile); @@ -206,7 +209,7 @@ Txy = cat(1, Txy, [tx ty]); end Txy = unique(Txy, 'rows'); - logger.logMessage(sprintf('<<< MonkeyLogic >>> Loaded & parsed conditions file: %s', condfile)) + logger.info('monkeylogic.m', sprintf('<<< MonkeyLogic >>> Loaded & parsed conditions file: %s', condfile)) drawnow; %Make certain all timing files are on the path: @@ -218,7 +221,7 @@ tfile = [MLPrefs.Directories.ExperimentDirectory tfarray{i}]; [pname fname] = fileparts(tfarray{i}); clear(fname); %force reload - logger.logMessage(sprintf('<<< MonkeyLogic >>> Embedding %s...', tfile)); + logger.info('monkeylogic.m', sprintf('<<< MonkeyLogic >>> Embedding %s...', tfile)); RunTimeFiles{i} = embedtimingfile(tfile, 'trialholder.m'); catch save(errorfile); @@ -226,9 +229,9 @@ end end if numtfiles == 1, - logger.logMessage('<<< MonkeyLogic >>> Successfully created the run-time function from the timing script'); + logger.info('monkeylogic.m', '<<< MonkeyLogic >>> Successfully created the run-time function from the timing script'); else - fprintf('<<< MonkeyLogic >>> Successfully created %i run-time functions from %i timing scripts...\n', numtfiles, numtfiles); + logger.info('monkeylogic.m', sprintf('<<< MonkeyLogic >>> Successfully created %i run-time functions from %i timing scripts...\n', numtfiles, numtfiles)); end drawnow; @@ -293,7 +296,7 @@ if MLConfig.Alerts.Enable, if isempty(MLConfig.Alerts.AlertFunction), MLConfig.Alerts.Enable = 0; - logger.logMessage('Warning: No alert function selected'); + logger.info('monkeylogic.m', 'Warning: No alert function selected'); else [pname fname ext] = fileparts(MLConfig.Alerts.AlertFunction); if strcmpi(ext, '.html') || strcmpi(ext, '.htm'), @@ -307,14 +310,14 @@ MLConfig.Alerts.WebPage.FTPdir = fgetl(fftp); MLConfig.Alerts.WebPage.Enable = 1; catch - logger.logMessage('Warning: Unable to gather required ftp info from "ftpinfo.txt"'); + logger.info('monkeylogic.m', 'Warning: Unable to gather required ftp info from "ftpinfo.txt"'); end fclose(fftp); if MLConfig.Alerts.WebPage.Enable, mlwebsummary(1, MLConfig, [fname '.html']); end else - logger.logMessage('Warning: No "ftpinfo.txt" file found for web updates...') + logger.info('monkeylogic.m', 'Warning: No "ftpinfo.txt" file found for web updates...') end MLConfig.Alerts.Enable = 0; %so only perform web page updates. else @@ -326,7 +329,7 @@ if MLConfig.Alerts.UserCriteria, if isempty(MLConfig.Alerts.UserCriteriaFunction), MLConfig.Alerts.UserCriteria = 0; - logger.logMessage('Warning: No function selected for user-defined alerts'); + logger.info('monkeylogic.m', 'Warning: No function selected for user-defined alerts'); else MLConfig.Alerts.UserCriteriaFunctionName = prep_m_file(MLConfig.Alerts.UserCriteriaFunction, MLPrefs.Directories); if isempty(MLConfig.Alerts.UserCriteriaFunctionName), @@ -339,7 +342,7 @@ end end -logger.logMessage('<<< MonkeyLogic >>> Initialized task parameters...') +logger.info('monkeylogic.m', '<<< MonkeyLogic >>> Initialized task parameters...') drawnow; % Get list of behavioral codes @@ -351,7 +354,7 @@ error('Error opening %s file', codesfile) BehavioralCodes = []; else - logger.logMessage(sprintf('<<< MonkeyLogic >>> Reading behavioral codes file: %s...', codesfile)) + logger.info('monkeylogic.m', sprintf('<<< MonkeyLogic >>> Reading behavioral codes file: %s...', codesfile)) fgetl(fidcodes); %get & discard header count = 0; while ~feof(fidcodes), @@ -367,12 +370,12 @@ end clear count codesfile header textline fidcodes; else - logger.logMessage('Warning: Behavioral codes text file not found...') + logger.info('monkeylogic.m', 'Warning: Behavioral codes text file not found...') BehavioralCodes = []; end % Open data file ("BHV" format) -logger.logMessage(sprintf('<<< MonkeyLogic >>> Opening %s...', datafile)); +logger.info('monkeylogic.m', sprintf('<<< MonkeyLogic >>> Opening %s...', datafile)); WriteData = struct([]); if appendflag == 0, fidbhv = fopen(datafile, 'w'); @@ -384,7 +387,7 @@ error('*** Unable to open data file: %s ***', datafile); end bhv_write(1, fidbhv, MLConfig, condfile, RunTimeFiles, Conditions, MLConfig.EyeTransform, MLConfig.JoyTransform); -fprintf('<<< MonkeyLogic >>> Initialized data file %s...\n', datafile); +logger.info('monkeylogic.m', sprintf('<<< MonkeyLogic >>> Initialized data file %s...', datafile)); MLConfig.DataFile = datafile; % Set up subject screen parameters @@ -465,7 +468,7 @@ daqreset; clear DaqInfo for i = 1:length(DaqError), - logger.logMessage(DaqError{i}); + logger.info('monkeylogic.m', DaqError{i}); save(errorfile); error('*** DAQ initialization error ***'); end @@ -476,7 +479,7 @@ JoystickInUse = ~ScreenInfo.UseRawJoySignal && ~isempty(DaqInfo.Joystick); TouchscreenInUse = ~ScreenInfo.UseRawTouchSignal && ~isempty(DaqInfo.TouchSignal); MouseInUse = ~ScreenInfo.UseRawMouseSignal && ~isempty(DaqInfo.MouseSignal); -fprintf('<<< MonkeyLogic >>> Successfully completed initializing I/O.\n'); +logger.info('monkeylogic.m', '<<< MonkeyLogic >>> Successfully completed initializing I/O.'); drawnow; % Initialize reward @@ -490,7 +493,7 @@ ScreenInfo.Half_xs = round(xs/2); ScreenInfo.Half_ys = round(ys/2); -logger.logMessage('<<< MonkeyLogic >>> Video graphics initialization started...'); +logger.info('monkeylogic.m', '<<< MonkeyLogic >>> Video graphics initialization started...'); ScreenInfo = init_video(ScreenInfo); if ~ScreenInfo.IsActive, @@ -499,10 +502,10 @@ save(errorfile); error('*** Video Initialization Error ***') end -logger.logMessage('<<< MonkeyLogic >>> Video graphics initialization completed successfully.') +logger.info('monkeylogic.m', '<<< MonkeyLogic >>> Video graphics initialization completed successfully.') % per MS: calculate video frame length for use with movies... -logger.logMessage('<<< MonkeyLogic >>> Calculating video frame length...') +logger.info('monkeylogic.m', '<<< MonkeyLogic >>> Calculating video frame length...') numframes = 10; flength = zeros(numframes, 2); k = 1000; @@ -515,7 +518,7 @@ flength(i, 2) = k*toc; end ScreenInfo.FrameLength = mean(mean(diff(flength(2:numframes, :)))); -fprintf('...Average video frame length = %2.3f ms\n', ScreenInfo.FrameLength); +logger.info('monkeylogic.m', sprintf('...Average video frame length = %2.3f ms', ScreenInfo.FrameLength)); drawnow; available_blocks = MLConfig.RunBlocks; @@ -549,7 +552,7 @@ RunTimeFiles{1} = embedtimingfile(timingfile, 'trialholder.m'); end C = initstim('initializing.avi', ScreenInfo); -[TaskObject ScreenInfo.ActiveVideoBuffers] = create_taskobjects(C, ScreenInfo, DaqInfo, TrialRecord, MLPrefs.Directories, logger, fidbhv); +[TaskObject ScreenInfo.ActiveVideoBuffers] = create_taskobjects(C, ScreenInfo, DaqInfo, TrialRecord, MLPrefs.Directories, fidbhv); TaskObject = initcontrolscreen(2, ScreenInfo, TaskObject); for i = 1:length(TaskObject), set(TaskObject(i).ControlObjectHandle, 'markeredgecolor', [0 0 0]); @@ -558,7 +561,7 @@ %TempScreenInfo.BackgroundColor = [0 0 0]; trialtype = 1; -fprintf('<<< MonkeyLogic >>> Initialization trial starting...\n'); +logger.info('monkeylogic.m', '<<< MonkeyLogic >>> Initialization trial starting...'); disable_cursor; disable_syskeys; @@ -581,7 +584,7 @@ enable_syskeys; clear TempScreenInfo C ssfile close_video(ScreenInfo, 'BuffersOnly'); -logger.logMessage(sprintf('<<< MonkeyLogic >>> Successfully initialized Timing Files.')) +logger.info('monkeylogic.m', sprintf('<<< MonkeyLogic >>> Successfully initialized Timing Files.')) if MLConfig.PreloadVideo, [preloaded ScreenInfo.PreloadedVideoBuffers] = preload_videos(Conditions,ScreenInfo); @@ -592,10 +595,10 @@ % Check to see if this run is simply a time-test... if thisisonlyatest, - logger.logMessage('<<< MonkeyLogic >>> Initializing Latency Test...') + logger.info('monkeylogic.m', '<<< MonkeyLogic >>> Initializing Latency Test...') C(1) = initstim('benchmarkpic.jpg', ScreenInfo); C(2) = initstim('initializing.avi', ScreenInfo); - [TaskObject ScreenInfo.ActiveVideoBuffers] = create_taskobjects(C, ScreenInfo, DaqInfo, TrialRecord, MLPrefs.Directories, logger, fidbhv); + [TaskObject ScreenInfo.ActiveVideoBuffers] = create_taskobjects(C, ScreenInfo, DaqInfo, TrialRecord, MLPrefs.Directories, fidbhv); TaskObject = initcontrolscreen(2, ScreenInfo, TaskObject); tfile = [MLPrefs.Directories.BaseDirectory 'mltimetest.m']; timingfile = embedtimingfile(tfile, 'trialholder.m'); @@ -610,7 +613,7 @@ error_escape(ScreenInfo, DaqInfo, fidbhv); clear DaqInfo save(errorfile); - logger.logMessage('<<<*** MonkeyLogic ***>>> Error running latency test') + logger.info('monkeylogic.m', '<<<*** MonkeyLogic ***>>> Error running latency test') varargout{1} = []; return end @@ -619,7 +622,7 @@ close_daq(DaqInfo); fclose(fidbhv); rmpath(MLPrefs.Directories.RunTimeDirectory); - logger.logMessage('<<< MonkeyLogic >>> Done.') + logger.info('monkeylogic.m', '<<< MonkeyLogic >>> Done.') return end @@ -629,14 +632,14 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% trialtype = 0; ScreenInfo.UsePreProcessedImages = MLConfig.UsePreProcessedImages; -logger.logMessage(sprintf('<<< MonkeyLogic >>> BHV File: %s. Started running trials at %s...', datafile, datestr(rem(now, 1)))); +logger.info('monkeylogic.m', sprintf('<<< MonkeyLogic >>> BHV File: %s. Started running trials at %s...', datafile, datestr(rem(now, 1)))); [pname fname] = fileparts(datafile); set(findobj('tag', 'mlmonitor'), 'name', sprintf('MonkeyLogic: %s Started running trials at %s %s', fname, datestr(rem(now, 1)), datestr(date))); drawnow; if MLConfig.Alerts.Enable, success = monkeylogic_alert(2, sprintf('Started running trials at %s %s', datestr(rem(now, 1)), datestr(date)), MLConfig.Alerts); if ~success, - logger.logMessage('Warning: Unable to send alerts...') + logger.info('monkeylogic.m', 'Warning: Unable to send alerts...') end end @@ -650,7 +653,7 @@ try %%%%% Start Monkeylogic in escape menu maxtrialsholder = -1; -[ScreenInfo, MLConfig, UserChanges] = check_keyboard(MLConfig, EyeSignalInUse, JoystickInUse, ScreenInfo, DaqInfo, TrialRecord, Instruction, logger); +[ScreenInfo, MLConfig, UserChanges] = check_keyboard(MLConfig, EyeSignalInUse, JoystickInUse, ScreenInfo, DaqInfo, TrialRecord, Instruction); if UserChanges.NewBlock, block = UserChanges.NewBlock; pausechangeblock = 1; @@ -736,7 +739,7 @@ enable_syskeys; mlhelper_stop; monkeylogic_alert(4, 'Error in user-defined Block-Change function', MLConfig.Alerts); - logger.logMessage('<<<*** MonkeyLogic ***>>> Error in user-defined Block-Change function') + logger.info('monkeylogic.m', '<<<*** MonkeyLogic ***>>> Error in user-defined Block-Change function') error_escape(ScreenInfo, DaqInfo, fidbhv); clear DaqInfo save(errorfile); @@ -821,7 +824,7 @@ enable_cursor; enable_syskeys; monkeylogic_alert(4, 'Block selection error in user-defined function', MLConfig.Alerts); - logger.logMessage('<<<*** MonkeyLogic ***>>> Block selection error in user-defined function') + logger.info('monkeylogic.m', '<<<*** MonkeyLogic ***>>> Block selection error in user-defined function') error_escape(ScreenInfo, DaqInfo, fidbhv); clear DaqInfo save(errorfile); @@ -835,7 +838,7 @@ enable_cursor; enable_syskeys; monkeylogic_alert(4, 'Error: selected block does not exist', MLConfig.Alerts); - logger.logMessage('<<<*** MonkeyLogic ***>>> Error: selected block does not exist') + logger.info('monkeylogic.m', '<<<*** MonkeyLogic ***>>> Error: selected block does not exist') error_escape(ScreenInfo, DaqInfo, fidbhv); clear DaqInfo save(errorfile); @@ -1084,7 +1087,7 @@ end % Generate / Load stimuli for this trial - [TaskObject ScreenInfo.ActiveVideoBuffers StimulusInfo] = create_taskobjects(C, ScreenInfo, DaqInfo, TrialRecord, MLPrefs.Directories, fidbhv, logger, pl); + [TaskObject ScreenInfo.ActiveVideoBuffers StimulusInfo] = create_taskobjects(C, ScreenInfo, DaqInfo, TrialRecord, MLPrefs.Directories, fidbhv, pl); TrialRecord.CurrentConditionStimulusInfo = StimulusInfo; %prepare control window objects @@ -1265,7 +1268,7 @@ if MLConfig.Alerts.Enable && MLConfig.Alerts.UserCriteria, success = monkeylogic_alert(3, TrialRecord, MLConfig.Alerts); if ~success, - logger.logMessage(sprintf('Warning: Unable to send user-defined alert...')) + logger.info('monkeylogic.m', sprintf('Warning: Unable to send user-defined alert...')) end end @@ -1280,7 +1283,7 @@ end %%%%%%%%%% while toc < 0.5 && ~UserChanges.QuitFlag, %will recognize keypresses within the first 500ms of the ITI - [ScreenInfo, MLConfig, UserChanges] = check_keyboard(MLConfig, EyeSignalInUse, JoystickInUse, ScreenInfo, DaqInfo, TrialRecord, Instruction, logger); + [ScreenInfo, MLConfig, UserChanges] = check_keyboard(MLConfig, EyeSignalInUse, JoystickInUse, ScreenInfo, DaqInfo, TrialRecord, Instruction); TrialRecord.EscapeQueued = 0; if UserChanges.NewBlock, block = UserChanges.NewBlock; @@ -1342,7 +1345,7 @@ if isempty(Instruction.Message), Instruction.Message = last_message; end - [ScreenInfo, MLConfig, UserChanges] = check_keyboard(MLConfig, EyeSignalInUse, JoystickInUse, ScreenInfo, DaqInfo, TrialRecord, Instruction, logger); + [ScreenInfo, MLConfig, UserChanges] = check_keyboard(MLConfig, EyeSignalInUse, JoystickInUse, ScreenInfo, DaqInfo, TrialRecord, Instruction); if UserChanges.NewBlock, block = UserChanges.NewBlock; pausechangeblock = 1; @@ -1369,7 +1372,7 @@ %%%%%%%%%%%%%%%%%% END TASKLOOP %%%%%%%%%%%%%%%%%%%%% catch ME - fprintf('<<<*** MonkeyLogic ***>>> Task Loop Execution Error\n%s\n',getReport(ME)); + logger.info('monkeylogic.m', sprintf('<<<*** MonkeyLogic ***>>> Task Loop Execution Error\n%s',getReport(ME))); cd(MLPrefs.Directories.BaseDirectory); unclip_cursor; enable_cursor; @@ -1429,8 +1432,8 @@ RESULT.TotalTrials = trial; figtitle = get(gcf, 'name'); set(gcf, 'name', [figtitle ' Finished at ' RESULT.FinishTime]); - logger.logMessage(sprintf('<<< MonkeyLogic >>> Finished running trials at %s.', RESULT.FinishTime)) - logger.logMessage(sprintf('<<< MonkeyLogic >>> Completed %i correct trials over %i total trials.', RESULT.CorrectTrials, RESULT.TotalTrials)) + logger.info('monkeylogic.m', sprintf('<<< MonkeyLogic >>> Finished running trials at %s.', RESULT.FinishTime)) + logger.info('monkeylogic.m', sprintf('<<< MonkeyLogic >>> Completed %i correct trials over %i total trials.', RESULT.CorrectTrials, RESULT.TotalTrials)) set(findobj('tag', 'mlmessagebox'), 'string', sprintf('Completed %i correct trials over %i total trials.', RESULT.CorrectTrials, RESULT.TotalTrials)); behaviorsummary('CurrentFile'); else @@ -1708,13 +1711,18 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -function [TaskObject, vbuffer, StimulusInfo] = create_taskobjects(C, ScreenInfo, DaqInfo, TrialRecord, mldirectories, fidbhv, logger, varargin) +function [TaskObject, vbuffer, StimulusInfo] = create_taskobjects(C, ScreenInfo, DaqInfo, TrialRecord, mldirectories, fidbhv, varargin) global errorfile %errorfile declared and initialized at the beginning of monkeylogic.m preloaded = []; if ~isempty(varargin), preloaded = varargin{1}; end +logger = log4m.getLogger('log.txt'); +logger.setCommandWindowLevel(logger.ALL); +logger.setLogLevel(logger.ALL); + + vbuffer = zeros(10000, 1); vbufnum = 0; @@ -1760,8 +1768,8 @@ fclose(fidbhv); %need to add code to finalize bhv file... str = sprintf('*** Error executing "gen" function %s', fname); % monkeylogic_alert(4, str, MLConfig.Alerts); - logger.logMessage(['<<< MonkeyLogic >>> ' str]); - logger.logMessage(getReport(ME)); + logger.info('monkeylogic.m', ['<<< MonkeyLogic >>> ' str]); + logger.info('monkeylogic.m', getReport(ME)); error_escape(ScreenInfo, DaqInfo, fidbhv); clear DaqInfo save(errorfile); @@ -2038,9 +2046,14 @@ vbuffer = vbuffer(1:vbufnum); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -function Instruction = parse_remote_command(RemoteCommand, PassCode, logger) +function Instruction = parse_remote_command(RemoteCommand, PassCode) persistent lastcommandtime +logger = log4m.getLogger('log.txt'); +logger.setCommandWindowLevel(logger.ALL); +logger.setLogLevel(logger.ALL); + + Instruction.Message = ' '; Instruction.Command = ' '; Instruction.Value = []; @@ -2063,7 +2076,7 @@ instruction = lower(RemoteCommand(1:f1-1)); passcode = RemoteCommand(f1+1:f2-1); if strcmp(passcode, PassCode), - logger.logMessage('<<<>>> Remote Access Accepted <<<>>>') + logger.info('monkeylogic.m', '<<<>>> Remote Access Accepted <<<>>>') if ~isempty(strfind(instruction, 'pause')) || ~isempty(strfind(instruction, 'timeout')) || ~isempty(strfind(instruction, 'hold')) || ~isempty(strfind(instruction, 'wait')), Instruction.Command = 'p'; Instruction.Message = 'Pause'; @@ -2145,10 +2158,10 @@ else Instruction.Message = 'Unknown remote command.'; end - logger.logMessage(sprintf('...Action: %s', Instruction.Message)) + logger.info('monkeylogic.m', sprintf('...Action: %s', Instruction.Message)) else Instruction.Message = 'Access Denied.'; - logger.logMessage('*** Unauthorized Access Attempted ***') + logger.info('monkeylogic.m', '*** Unauthorized Access Attempted ***') end end @@ -2283,7 +2296,7 @@ function update_error_lists(trialerror, originalcond, cond, ScreenInfo) end ScreenInfo.ActiveVideoBuffers(~ScreenInfo.ActiveVideoBuffers) = []; if any(ScreenInfo.ActiveVideoBuffers), - logger.logMessage('WARNING: *** Unable to release all active video buffers ***') + logger.info('monkeylogic.m', 'WARNING: *** Unable to release all active video buffers ***') end if ~isempty(varargin) && strcmpi(varargin{1}, 'BuffersOnly'), @@ -2297,7 +2310,7 @@ function update_error_lists(trialerror, originalcond, cond, ScreenInfo) end ScreenInfo.PreloadedVideoBuffers(~ScreenInfo.PreloadedVideoBuffers) = []; if any(ScreenInfo.PreloadedVideoBuffers), - logger.logMessage('WARNING: *** Unable to release all active video buffers ***') + logger.info('monkeylogic.m', 'WARNING: *** Unable to release all active video buffers ***') end end @@ -2343,10 +2356,14 @@ function close_daq(DaqInfo) clear DaqInfo %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -function [ScreenInfo, MLConfig, UserChanges] = check_keyboard(MLConfig, EyeSignalInUse, JoystickInUse, ScreenInfo, DaqInfo, TrialRecord, Instruction, logger) +function [ScreenInfo, MLConfig, UserChanges] = check_keyboard(MLConfig, EyeSignalInUse, JoystickInUse, ScreenInfo, DaqInfo, TrialRecord, Instruction) global MLHELPER_OFF global RFM_TASK +logger = log4m.getLogger('log.txt'); +logger.setCommandWindowLevel(logger.ALL); +logger.setLogLevel(logger.ALL); + startmenu = TrialRecord.CurrentTrialNumber == 0; escapequeued = 0; if isfield(TrialRecord,'EscapeQueued'), @@ -2599,7 +2616,7 @@ function close_daq(DaqInfo) end fclose(fid2); end - Instruction = parse_remote_command(RemoteCommand, MLConfig.Alerts.WebPage.PassCode, logger); + Instruction = parse_remote_command(RemoteCommand, MLConfig.Alerts.WebPage.PassCode); remotecommand = any('qr' == Instruction.Command); if remotecommand, if Instruction.Command == 'r', @@ -2642,7 +2659,7 @@ function goodmonkey(duration, varargin) end if noreward, - logger.logMessage('WARNING: *** No reward output defined ***') + logger.info('monkeylogic.m', 'WARNING: *** No reward output defined ***') return end @@ -2719,7 +2736,7 @@ function mlmessage(str) function disable_cursor global MLHELPER_OFF if MLHELPER_OFF, - %logger.logMessage('disable_cursor MLHELPER_OFF'); + %logger.info('monkeylogic.m', 'disable_cursor MLHELPER_OFF'); return end thisfig = get(0,'CurrentFigure'); @@ -2736,7 +2753,7 @@ function mlmessage(str) function enable_cursor global MLHELPER_OFF if MLHELPER_OFF, - %logger.logMessage('enable_cursor MLHELPER_OFF'); + %logger.info('monkeylogic.m', 'enable_cursor MLHELPER_OFF'); return end thisfig = get(0,'CurrentFigure');