


import_cal_erps() - Read the cal pulses from a crw file, construct the
average of the pulses that were used to calibrate the
data (i.e., were not trimmed).
Usage:
cal_erps=import_cal_erps(Results,cal_crwfile,cal_logfile,cal_blfORbdf_file,rm_chans,usedcal_itemnum,scale_factor)
Required Inputs:
Results = the input parser "p.Results" variable from crw2set. The fields of Results
used in this function are:
Results.presam
Results.cprecis
Results.decimat
cal_crwfile = crw file from which the calibration pulses will be
taken
cal_logfile = log file for the crw file from which the calibration
pulses will be taken
cal_blfORbdf_file = bdf or blf file for the crw file from which the
calibration pulses will be taken
rm_chans = string or cell array specifying the names of any
channels that should not be imported to set file
(e.g., a horizontal eye montage). (default: [])
usedcal_itemnum = 2D matrix (channels x pulses) indicating the log
item numbers of the pulses that were used to calibrate
the data for each channel. It is produced by
trm_raw2nrm.m.
scale_factor = vector containing the values by which to scale each
channel to make the data in units of microvolts. For example,
if you divide the first channel's data by the first
element of scale factor, its data will now be in
microvolts. It is produced by trm_raw2nrm.m.
NOTE: All file names should be strings and should include the
file's path unless the file is the current working directory.
Outputs:
cal_erps = 2D matrix (channels x time points) mean cal pulses. The means
are trimmed if trimmeing was requested when trm_raw2nrm was
used. The cal pulses are baselined according to the values of
'low_cursor', 'hi_cursor, and 'cal_npts' (parameters of crw2set.m).
Notes:
-Function assumes that cal pulses are all assigned to a single bin with a
Condition Code of 0
Author:
David Groppe (based on code written by Tom Urbach),
Kutaslab, 11/2009

0001 function cal_erps=import_cal_erps(Results,cal_crwfile,cal_logfile,cal_blfORbdf_file,rm_chans,usedcal_itemnum,scale_factor) 0002 % 0003 % import_cal_erps() - Read the cal pulses from a crw file, construct the 0004 % average of the pulses that were used to calibrate the 0005 % data (i.e., were not trimmed). 0006 % 0007 % 0008 % Usage: 0009 % cal_erps=import_cal_erps(Results,cal_crwfile,cal_logfile,cal_blfORbdf_file,rm_chans,usedcal_itemnum,scale_factor) 0010 % 0011 % 0012 % Required Inputs: 0013 % Results = the input parser "p.Results" variable from crw2set. The fields of Results 0014 % used in this function are: 0015 % Results.presam 0016 % Results.cprecis 0017 % Results.decimat 0018 % 0019 % cal_crwfile = crw file from which the calibration pulses will be 0020 % taken 0021 % 0022 % cal_logfile = log file for the crw file from which the calibration 0023 % pulses will be taken 0024 % 0025 % cal_blfORbdf_file = bdf or blf file for the crw file from which the 0026 % calibration pulses will be taken 0027 % 0028 % rm_chans = string or cell array specifying the names of any 0029 % channels that should not be imported to set file 0030 % (e.g., a horizontal eye montage). (default: []) 0031 % 0032 % usedcal_itemnum = 2D matrix (channels x pulses) indicating the log 0033 % item numbers of the pulses that were used to calibrate 0034 % the data for each channel. It is produced by 0035 % trm_raw2nrm.m. 0036 % 0037 % scale_factor = vector containing the values by which to scale each 0038 % channel to make the data in units of microvolts. For example, 0039 % if you divide the first channel's data by the first 0040 % element of scale factor, its data will now be in 0041 % microvolts. It is produced by trm_raw2nrm.m. 0042 % 0043 % NOTE: All file names should be strings and should include the 0044 % file's path unless the file is the current working directory. 0045 % 0046 % 0047 % Outputs: 0048 % cal_erps = 2D matrix (channels x time points) mean cal pulses. The means 0049 % are trimmed if trimmeing was requested when trm_raw2nrm was 0050 % used. The cal pulses are baselined according to the values of 0051 % 'low_cursor', 'hi_cursor, and 'cal_npts' (parameters of crw2set.m). 0052 % 0053 % Notes: 0054 % -Function assumes that cal pulses are all assigned to a single bin with a 0055 % Condition Code of 0 0056 % 0057 % Author: 0058 % David Groppe (based on code written by Tom Urbach), 0059 % Kutaslab, 11/2009 0060 % 0061 0062 %%%%%%%%%%%%%%%% REVISION LOG %%%%%%%%%%%%%%%%% 0063 % 0064 0065 global VERBLEVEL 0066 0067 VerbReport('Creating cal pulse ERPs with minimal memory demands.', 3, VERBLEVEL); 0068 0069 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0070 % I. OPEN CAL PULSE CRW FILE USING ERPIO() & GET EXP INFO AND RECORDING PARAMETERS 0071 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0072 fid_crw=erpio('openraw',cal_crwfile,cal_logfile,Results.presam,Results.cprecis,Results.decimat); 0073 if (erpio('get_errno') == 0), 0074 VerbReport(sprintf('Opening cal pulse crw file %s went OK', cal_crwfile), 2, VERBLEVEL); 0075 else 0076 error(erpio('get_errstr')); 0077 end; 0078 0079 % Get experiment info and recording parameters 0080 VerbReport('Getting cal pulse crw file header information.', 3, VERBLEVEL); 0081 0082 %Note: these aren't necessary, but worth reporting 0083 expdesc = erpio('get_hdrvar', fid_crw, 'expdesc', 0); 0084 subdesc = erpio('get_hdrvar', fid_crw, 'subdesc', 0); 0085 VerbReport(sprintf('Cal crw File Exp Desc: %s',expdesc), 3, VERBLEVEL); 0086 VerbReport(sprintf('Cal crw File Sub Desc: %s',subdesc), 3, VERBLEVEL); 0087 0088 %Necessary 0089 nchans = erpio('get_hdrvar', fid_crw, 'chans',0); 0090 crw_chanlabels=cell(1,nchans); 0091 for a=1:nchans, 0092 crw_chanlabels{a}=erpio('get_hdrvar',fid_crw,'chndesc',a-1); 0093 % "a-1" because indexing starts at 0 0094 end 0095 tpts = 256*Results.cprecis; 0096 srate=100000/erpio('get_hdrvar',fid_crw,'clktick','junk'); 0097 0098 % Figure out which channels to use 0099 use_chans=1:nchans; 0100 use_crw_chanlabels=cell(1,1); 0101 use_chan_ct=0; 0102 if ~isempty(rm_chans), 0103 for a=1:nchans, 0104 for b=1:length(rm_chans), 0105 if strcmpi(crw_chanlabels{a},rm_chans{b}), 0106 use_chans(a)=-1; 0107 break; %break b loop 0108 end 0109 end 0110 if use_chans(a)>0 0111 use_chan_ct=use_chan_ct+1; 0112 use_crw_chanlabels{use_chan_ct}=crw_chanlabels{a}; 0113 end 0114 end 0115 use_chans=use_chans(find(use_chans>0)); 0116 else 0117 use_crw_chanlabels=crw_chanlabels; 0118 end 0119 nchans=length(use_chans); 0120 0121 0122 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0123 % II. IMPORT BLF FILE INFORMATION 0124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0125 orig_level=VERBLEVEL; 0126 VERBLEVEL=1; %suppress reporting bin descriptors again 0127 [blf_info, bin_LongDesc, blffile, blf_evnum]=import_blf(cal_blfORbdf_file,cal_logfile, ... 0128 srate,[]); 0129 VERBLEVEL=orig_level; 0130 0131 %Remove unnecessary vars 0132 clear blf_info bin_LongDesc 0133 0134 %blf_evnum is necessary for screening out any events in the logfile 0135 %that were not caught by the blf file 0136 0137 0138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0139 % III. IMPORT LOG INFO FROM ASCII VERSION OF CAL_LOGFILE 0140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0141 VerbReport(' ',1,VERBLEVEL); 0142 %Create temporary ascii version of cal_logfile 0143 VerbReport(sprintf('Creating temporary ascii version of logfile %s for calibration pulses',cal_logfile),1,VERBLEVEL); 0144 %remove temp_cal.asci if it exists 0145 asci_cmnd='rm -f temp_cal.asci'; 0146 unix(asci_cmnd); 0147 asci_cmnd=sprintf('log2asci %s temp_cal.asci -d %d',cal_logfile,srate); 0148 [s, w]=unix(asci_cmnd); 0149 if s~=0, 0150 disp('Could not create ascii version of logfile using log2asci.'); 0151 error('According to log2asci: %s',w); 0152 end 0153 asciilogfile='temp_cal.asci'; 0154 VerbReport(sprintf('Getting log information from %s', asciilogfile), 1, VERBLEVEL); 0155 0156 0157 % Load log information ... 0158 enum = []; ecode = []; ccode = []; flag =[]; tick = []; sec =[]; deltaT = []; 0159 %check to find out how ascii version of log file was created 0160 fid_ascii=fopen(asciilogfile,'r'); 0161 lyne=fgetl(fid_ascii); %read in first line 0162 for dumb_loop=1:13, 0163 lyne=fgetl(fid_ascii); %read in headerlines 0164 end 0165 if strcmpi(lyne(length(lyne)-4:end),'Delta') %file was generated with sampling rate 0166 fclose(fid_ascii); 0167 [enum, ecode, ccode, flag, tick, sec, deltaT]=textread(asciilogfile,['%d' ... 0168 ' %d %d %d %d %f %f'],'headerlines',14); 0169 else 0170 err_str=sprintf('ERROR: ASCII version of logfile %s was not generated with sampling rate.\n', ... 0171 asciilogfile); 0172 error([err_str 'Please correct.']); 0173 end 0174 log_file_info = [enum, ecode, ccode, flag, sec]; 0175 0176 %Select only cal_logfile information for events that are listed in the 0177 %blf file 0178 log_info=zeros(size(blf_evnum,1),5); %preallocate memory 0179 ct=0; 0180 for blf_ev=blf_evnum, 0181 ct=ct+1; 0182 log_info(ct,:) = log_file_info(find(enum==blf_ev),:); 0183 end 0184 0185 %If a temp ascii version of cal_logfile was created, delete it 0186 if ~isempty(asci_cmnd) 0187 VerbReport(sprintf('Removing temporary ascii version of logfile.'),1,VERBLEVEL); 0188 asci_cmnd='rm -f temp_cal.asci'; 0189 [s, w]=unix(asci_cmnd); 0190 if s~=0, 0191 disp('Could not remove ascii version of logfile: temp_cal.asci.'); 0192 error('According to rm: %s',w); 0193 end 0194 end 0195 0196 0197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0198 % IV. READ CAL PULSES ... 0199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0200 VerbReport(sprintf('\nGetting epochs from %s', cal_crwfile), 1, VERBLEVEL); 0201 0202 % NAB NUMBER OF EPOCHS THE BLF FILE KNOWS ABOUT 0203 nep = size(log_info,1); 0204 0205 % INITIALIZE DATA AND INFO ARRAYS W/ MAX POSSIBLE EPOCHS THO 0206 % MAY BE FEWER IF EEG DATA READ FAILURES ... 0207 nom_cal_size = sum(log_info(:,3)==0); 0208 0209 %Assumes calibration condition code is 0 0210 VerbReport('Assuming Condition Code 0=calibration pulses.',1,VERBLEVEL); 0211 VerbReport(sprintf('%d total calibration pulses from cal crw file',nom_cal_size), 1, VERBLEVEL); 0212 0213 0214 %Initialize pulse variables 0215 runningsum=zeros(nchans,tpts); 0216 0217 %sum_itemnums=zeros(nchans,nom_cal_size); %Used for debugging only. Keeps 0218 %track of which log items were included in the cal pulse ERP for each 0219 %channel 0220 0221 % Find pre and post pulse time windows for measuring pulse amplitude 0222 %peristimulus time of each time point in milliseconds 0223 tme=1000*((1:256*Results.cprecis)-1)/srate; 0224 tme=tme-Results.presam; 0225 [dummy, low_cntr_samp]=min(abs(Results.low_cursor-tme)); 0226 [dummy, hi_cntr_samp]=min(abs(Results.hi_cursor-tme)); 0227 0228 %Pre-Pulse time window (in samples) 0229 lo_start_samp = low_cntr_samp-floor(Results.cal_npts/2); 0230 lo_stop_samp = low_cntr_samp+floor(Results.cal_npts/2); 0231 prewind=[tme(lo_start_samp) tme(lo_stop_samp)]; 0232 0233 %Useful for debugging 0234 %Post-pulse time window (in samples) 0235 %hi_start_samp = hi_cntr_samp-floor(Results.cal_npts/2); 0236 %hi_stop_samp = hi_cntr_samp+floor(Results.cal_npts/2); 0237 %postwind=[tme(hi_start_samp) tme(hi_stop_samp)]; 0238 % After normalization, the mean amplitude between hi_start_samp and 0239 % hi_stop_samp [mean(cal_erps(:,hi_start_samp:hi_stop_samp),2)] should be 0240 % the cal pulse amplitude in microvolts at all channels. 0241 0242 %Count # of calibration epochs actually loaded 0243 calcnt=zeros(1,length(use_chans)); 0244 for i=1:nep, 0245 0246 % ATTEMPT TO NAB EPOCH ... ERPIO RETURNS EMPTY ARRAY IF IT DOESN'T WORK 0247 currdat = zeros(nchans,tpts); 0248 currdat = erpio('evread', fid_crw, log_info(i, 1)); 0249 0250 % BRANCH ON CONDITION CODE FOR CALS VS. ALL OTHER EVENTS 0251 if (log_info(i,3)==0), 0252 if isempty(currdat) 0253 % DON'T LOAD ANYTHING IF THERE IS NO DATA BUT CONTINUE 0254 msg=sprintf(['erpio: Can not read data at log item %d.\n' ... 0255 'Log item should be a calibration pulse.'],log_info(i,1)); 0256 watchit(msg); 0257 else 0258 %remove pre-pulse baseline 0259 currdat=rmbase(currdat,tpts,lo_start_samp:lo_stop_samp); 0260 0261 chn_ct=0; 0262 for chnloop=use_chans, 0263 chn_ct=chn_ct+1; 0264 %if cal pulse was used (i.e., not trimmed) 0265 if ismember(log_info(i,1),usedcal_itemnum(chn_ct,:)), 0266 calcnt(chn_ct)=calcnt(chn_ct)+1; 0267 0268 %record logitem number of pulse<--useful for debugging 0269 %sum_itemnums(chn_ct,calcnt(chn_ct))=log_info(i,1); 0270 0271 runningsum(chn_ct,:)=runningsum(chn_ct,:)+currdat(chnloop,:); 0272 VerbReport(sprintf('Loading cal %d/%d event (blf event %d/%d) for channel %s.', ... 0273 calcnt(chn_ct),nom_cal_size,i,nep,use_crw_chanlabels{chn_ct}),3,VERBLEVEL); 0274 0275 else 0276 VerbReport(sprintf('The cal pulse corresponding to blf event %d/%d has been trimmed for channel %s.', ... 0277 i,nep,use_crw_chanlabels{chn_ct}),3,VERBLEVEL); 0278 end 0279 end 0280 end 0281 elseif (log_info(i,3)<0) 0282 error('Unexplained negative condition code at log item %d.', i); 0283 end 0284 end 0285 erpio('close', fid_crw) 0286 0287 0288 % Check to make sure we've used the correct number of cal pulses for each 0289 % channel 0290 n_orig_pulses=size(usedcal_itemnum,2); 0291 ids=find(calcnt~=n_orig_pulses); 0292 if ~isempty(ids), 0293 err_chan=[]; 0294 for id_loop=ids, 0295 err_chan=[err_chan use_crw_chanlabels(id_loop)]; 0296 end 0297 error('Channels %s do not have the same number of used calibration pulses as were used by trm_raw2nrm.m',err_chan); 0298 end 0299 0300 %turn sum into mean 0301 cal_erps=runningsum./repmat(calcnt',1,tpts); 0302 cal_erps=cal_erps./repmat(scale_factor,1,tpts); %scale to microvolts 0303 0304 VerbReport('', 1, VERBLEVEL); 0305 VerbReport(sprintf('Done creating cal pulse ERP from %s\n',cal_crwfile), 3, VERBLEVEL); 0306 %remove temp mkp files in case they exist 0307 if strcmpi(blffile,'temp.blf'), 0308 VerbReport('Removing temporary files: temp.rt, temp.blf', 2, VERBLEVEL); 0309 unix('rm -f temp.blf'); 0310 unix('rm -f temp.rt'); 0311 end 0312 VerbReport('', 1, VERBLEVEL); 0313