Home > fmri > utils > physio > proc_physio.m

proc_physio

PURPOSE ^

phys = proc_physio(subid, expanme);

SYNOPSIS ^

function phys = proc_physio(ps)

DESCRIPTION ^

 phys = proc_physio(subid, expanme);

 ps - is a structure returned by init_phys_struct which contains all of the
      information necessary to perform the conversion.

 Adapted from modfmri/convert_physio.m

 Wrapper for script which converts ASCII file with physiological monitoring
 data into a mat file that can then be used for design matrix creation.

 The intent of this function is for it to ultimately handle multiple types of
 input data formats

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function phys = proc_physio(ps)
0002 % phys = proc_physio(subid, expanme);
0003 %
0004 % ps - is a structure returned by init_phys_struct which contains all of the
0005 %      information necessary to perform the conversion.
0006 %
0007 % Adapted from modfmri/convert_physio.m
0008 %
0009 % Wrapper for script which converts ASCII file with physiological monitoring
0010 % data into a mat file that can then be used for design matrix creation.
0011 %
0012 % The intent of this function is for it to ultimately handle multiple types of
0013 % input data formats
0014 %
0015 
0016 % 10/27/05 Petr Janata - adapted script
0017 insane = 0;  % Flag for something having gone quite wrong
0018 phys = [];
0019 
0020 % Extract some variables from the ps struct
0021 sinfo = ps.sinfo;
0022 sid = sinfo.id;
0023 pp = ps.pp;
0024 logfid = ps.logfid;
0025 
0026 phys_fname = fullfile(ps.datapath, sid, sprintf('%s%s%s', sid,ps.phys_data_stub,ps.phys_data_suffix));
0027 check_exist(phys_fname);
0028 
0029 % Call the parser
0030 ri = read_physmon(phys_fname, ps.pp);
0031 
0032 % Eliminate a run up front if desired
0033 if ~isempty(ps.elim_runs)
0034   fprintf(logfid, 'Eliminating run(s) %s\n', sprintf('%d ', ps.elim_runs));
0035   ri(ps.elim_runs) = [];
0036 end
0037 
0038 % Number of runs is determined by runs flagged for analysis in
0039 % get_<expname>_sinfo.m
0040 use_runs = sinfo.use_runs;
0041 nruns = length(use_runs);
0042 
0043 if nruns ~= length(ri)
0044   error_str = sprintf('ERROR:proc_physio:Expected %d runs, detected %d\n', nruns, length(ri));
0045   fprintf(logfid, error_str);
0046   error(error_str);
0047   return
0048 else
0049   for irun = 1:nruns
0050     ri(irun).id = use_runs(irun);
0051   end
0052 end
0053 
0054 %
0055 % NOTE, from here on out, we assume that the entries in ri reflect the runs
0056 % specified in sinfo.use_run
0057 %
0058 
0059 %
0060 % Perform some data integrity checks
0061 %
0062 fprintf(logfid, 'Performing data integrity checks ...\n');
0063 
0064 
0065 ps.expect.nslice = sum(sinfo.nvol(use_runs)*ps.nslice_per_vol);
0066 
0067 if nruns ~= ps.expect.nruns
0068   fprintf(logfid,'WARNING:proc_physio:Really wanted %d runs; found %d\n', ps.expect.nruns, nruns);
0069   insane = 0;
0070   
0071   % Change expectations for number of events given non-canonical number of
0072   % runs.
0073   ps.expect.pos_events = nruns*ps.expect.pos_events_per_run;
0074   ps.expect.neg_events = nruns*ps.expect.neg_events_per_run;
0075 end
0076 
0077 npos = length(cat(1,ri.pos_events));
0078 if npos ~= ps.expect.pos_events
0079   fprintf(logfid,'WARNING:proc_physio:Expected %d positive markers, detected %d\n', ps.expect.pos_events, npos);
0080   insane = 1;
0081 end
0082 
0083 nneg = length(cat(1,ri.neg_events));
0084 if ~any(ismember(nneg, ps.expect.neg_events))
0085   fprintf(logfid,'WARNING:proc_physio:Expected %d negative markers, detected %d\n', ps.expect.neg_events(1), nneg);
0086   insane = 1;
0087 end
0088 
0089 nslice = length(cat(1,ri.slice_onsets));
0090 nslice_per_vol = ps.nslice_per_vol;
0091 if nslice ~= ps.expect.nslice
0092   for irun = 1:nruns
0093     run_idx = ri(irun).id;  % use this to index into original sinfo structures
0094     expect_nslice = sinfo.nvol(run_idx)*nslice_per_vol;
0095     actual_nslice = length(ri(irun).slice_onsets);
0096     if actual_nslice ~= expect_nslice
0097       fprintf(logfid,'WARNING:proc_physio:Run %d: Expected %d slices, detected %d\n', irun, expect_nslice, actual_nslice);
0098 
0099       if expect_nslice == actual_nslice-nslice_per_vol
0100     ndiff = actual_nslice-expect_nslice;
0101     fprintf(logfid,'Eliminating %d excess slices from beginning of run %d\n', ndiff, irun);
0102     
0103     % When volumes are dropped, they are dropped at the beginning of the
0104     % run.  Therefore, all timing info has to be changed to accommodate this.
0105     ri(irun).slice_onsets(1:ndiff) = [];
0106     
0107     new_start_time = ri(irun).slice_onsets(1);
0108     
0109     ri(irun).slice_onsets = ri(irun).slice_onsets - new_start_time;
0110     
0111     ri(irun).pos_events(2:end) = ...
0112         ri(irun).pos_events(2:end)-new_start_time;
0113     ri(irun).neg_events = ri(irun).neg_events - new_start_time;
0114     ri(irun).key_events = ri(irun).key_events - new_start_time;
0115     
0116     ri(irun).cardiac = ri(irun).cardiac - new_start_time;
0117     elim_idx = find(ri(irun).cardiac < 0);
0118     ri(irun).cardiac(elim_idx) = [];
0119     
0120     elim_idx = find(((0:length(ri(irun).respir)-1)/pp.Fs ...
0121         -new_start_time) < 0);
0122     ri(irun).respir(elim_idx) = [];
0123       elseif expect_nslice < actual_nslice
0124     % Scanner crash scenario
0125     ndiff = actual_nslice-expect_nslice;
0126     fprintf(logfid,'Eliminating %d excess slices from end of run %d\n', ndiff, irun);
0127     ri(irun).slice_onsets(actual_nslice ...
0128         -(actual_nslice-expect_nslice)+1:end) = []; 
0129     
0130     % Eliminate all responses and event markers that occurred after
0131     % scanner quit saving the data
0132     stop_time = ri(irun).slice_onsets(end);
0133     bad_idx = find(ri(irun).pos_events > stop_time);
0134     ri(irun).pos_events(bad_idx) = [];
0135 
0136     bad_idx = find(ri(irun).neg_events > stop_time);
0137     ri(irun).neg_events(bad_idx) = [];
0138 
0139     bad_idx = find(ri(irun).key_events > stop_time);
0140     ri(irun).key_events(bad_idx) = [];
0141 
0142     % Let us capture next heartbeat so that we can compute phase in
0143     % cardiac cycle during design matrix construction
0144     bad_idx = find(ri(irun).cardiac > stop_time + ps.cardiac_slop_s);
0145     ri(irun).cardiac(bad_idx) = [];
0146 
0147     bad_idx = find((0:length(ri(irun).respir)-1)/pp.Fs > stop_time);
0148     ri(irun).respir(bad_idx) = [];
0149     
0150       else
0151     insane = 1;
0152       end
0153     end
0154   end % for irun = 1:nruns
0155 end % if nslice ~= expect.nslice
0156 
0157 ps.insane = insane;
0158 if insane
0159   fprintf(logfid,'\tErrors detected!\n');
0160 else
0161   fprintf(logfid,'\tNo errors found\n');
0162 end
0163 
0164 % Pack the return structure
0165 phys.ps = ps;
0166 phys.ri = ri;
0167 
0168 if pp.savedata
0169   phys_matname = fullfile(ps.datapath, sid, sprintf('%s_phys.mat', sid));
0170   fprintf(logfid,'Saving physio information to: %s\n', phys_matname);
0171   save(phys_matname, 'phys')
0172 end
0173 
0174 return

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