Home > fmri > utils > check_pulse_periods.m

check_pulse_periods

PURPOSE ^

[r] = check_pulse_periods(pulse_times,params)

SYNOPSIS ^

function [r] = check_pulse_periods(pulse_times,params,r)

DESCRIPTION ^

 [r] = check_pulse_periods(pulse_times,params)

 Given a vector of event onset times, e.g. MRI scanner pulses, that are
 expected to have a constant period, the script identifies aberrent pulse periods

 pulse_times - vector of pulse times (msec)

 r is the reporting structure which contains a data structure with the
 following fields:
 bad_pulse_period_mask - logical vector indicating which pulse periods are
                         aberrant.  The first element in this vector refers to
                         the period between the first and second elements in
                         the pulse_times vector.
 pulse_period_too_short_mask - those periods that were too short
 pulse_period_too_long_mask - those periods that were too long
 nmiss - estimate of number of missed pulses
 median_period - estimate of the median pulse period
 msglog - list of all messages that were generated

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [r] = check_pulse_periods(pulse_times,params,r)
0002 % [r] = check_pulse_periods(pulse_times,params)
0003 %
0004 % Given a vector of event onset times, e.g. MRI scanner pulses, that are
0005 % expected to have a constant period, the script identifies aberrent pulse periods
0006 %
0007 % pulse_times - vector of pulse times (msec)
0008 %
0009 % r is the reporting structure which contains a data structure with the
0010 % following fields:
0011 % bad_pulse_period_mask - logical vector indicating which pulse periods are
0012 %                         aberrant.  The first element in this vector refers to
0013 %                         the period between the first and second elements in
0014 %                         the pulse_times vector.
0015 % pulse_period_too_short_mask - those periods that were too short
0016 % pulse_period_too_long_mask - those periods that were too long
0017 % nmiss - estimate of number of missed pulses
0018 % median_period - estimate of the median pulse period
0019 % msglog - list of all messages that were generated
0020 
0021 % 05/12/06 Petr Janata - updated code with additional error checking
0022 % 08/03/06 PJ - implemented within the emerging reporting framework
0023 % 12/11/07 PJ - fixed minor bug in which nmiss was not being created when
0024 %               no pulses were missed
0025 
0026 r.type = 'pulse_period_check';  % Identify the type of this reporting instance
0027 r.report_on_fly = 1;
0028 
0029 try max_pulse_dev = params.max_pulse_dev; catch
0030   max_pulse_dev = 20; % maximum deviation (in msec) of a pulse from the expected
0031                      % period.
0032 end
0033 
0034 try min_pulse_period = params.min_pulse_period; catch
0035   min_pulse_period = 50;  % won't be going faster than 20 slices/sec
0036 end
0037 
0038 % Look at variability of timing pulses, and check for skipped pulses
0039 pulse_periods = diff(pulse_times);  % determine all of the pulse periods
0040 median_period = median(pulse_periods);
0041 
0042 % Check to see if the median pulse period is too short
0043 pulse_period_too_short_mask = zeros(size(pulse_periods));
0044 if median_period < min_pulse_period
0045   msg = sprintf(['Median pulse period (%4.1f) is less than minimum allowed ' ...
0046     'period (%4.1f)'], median_period, min_pulse_period)
0047   r = update_report(r,msg);
0048  
0049   pulse_period_too_short_mask = pulse_periods < min_pulse_period;
0050   msg = sprintf('Detected %d pulse periods that were too short\n', sum(pulse_period_too_short_mask));
0051   r = update_report(r,msg);
0052   
0053   % Revise the median pulse period estimate
0054   median_period = median(pulse_periods(~pulse_period_too_short_mask));
0055 end
0056 
0057 % Check for pulse periods that are too long
0058 pulse_period_too_long_mask = pulse_periods > median_period+max_pulse_dev;
0059 bad_pulse_period_idxs = find(pulse_period_too_long_mask);
0060 
0061 nbad = length(bad_pulse_period_idxs);
0062 nmiss = 0;
0063 if nbad
0064   msg = sprintf('Detected %d pulse periods that were too long\n', nbad);
0065   r = update_report(r,msg);
0066 
0067   % Estimate the number of missed pulses
0068   for ibad = 1:nbad
0069     nmiss = nmiss + round(pulse_periods(bad_pulse_period_idxs(ibad))/median_period)-1;
0070   end % for ibad=
0071   msg = sprintf('Estimate of %d missed pulses\n', nmiss);
0072   r = update_report(r,msg);
0073 end
0074 
0075 % Pulse periods that are too long aren't technically bad in that there are only
0076 % pulses missing.  Short pulse periods are bad though, so add them to the bad_pulse_period_mask.
0077 r.data.bad_pulse_period_mask = pulse_period_too_short_mask; % | pulse_period_too_long_mask;
0078 r.data.pulse_period_too_short_mask = pulse_period_too_short_mask;
0079 r.data.pulse_period_too_long_mask = pulse_period_too_long_mask;
0080 r.data.nmiss = nmiss;
0081 r.data.median_period = median_period;

Generated on Wed 20-Sep-2023 04:00:50 by m2html © 2003