function loadxsil(fname,debug) % % Syntax: loadxsil(Filename [, debug]) % % filename is a string the xsil file to load, e.g. 'foo.xsil' % debug is optional and specifies the level of debugging information % debug = 0 is no debugging % " = 1 displays lines to be evaluated before evaluating % " = 2 displays the lines to be evaluated without evaluating % % Copyright (C) 2003-2004 % % Code contributed by Paul Cochrane % % This file is part of xmds. % % This program is free software; you can redistribute it and/or % modify it under the terms of the GNU General Public License % as published by the Free Software Foundation; either version 2 % of the License, or (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. % % $Id: loadxsil.m,v 1.14 2005/04/28 05:21:04 joehope Exp $ if nargin == 0 disp('Must specify a filename. See help loadxsil') return end strOut = sprintf('%s%s','Parsing xsil file: ', fname); disp(strOut) % debug: 0 show no info % 1 show lines to be evaluated and evaluate % 2 show lines to be evaluated but do not evaluate if nargin == 1 debug = 0; % just a variable useful for testing stuff else strOut = sprintf('%s%d','Using debug level: ', debug); disp(strOut) end clear strOut; % open the xsil file for reading fp = fopen(fname,'r'); if (fp == -1) disp('cannot open xsil file') disp('exiting...') return end binaryFound = 0; singleFound = 0; samplesFound = 0; while 1 line = fgetl(fp); % if we get to the end of the file, break out of loop if ~isstr(line), break, end while (isempty(findstr(line,''); %binaryElement = line(indStart+15:indEnd-1); %if (strcmp(binaryElement,'yes')) % useBinary = 1; %elseif (strcmp(binaryElement,'no')) % useBinary = 0; %end end % look for precision="single" (double is the default) indStart = findstr(line, 'precision="single"'); if (~isempty(outputFound) & ~isempty(indStart) & singleFound == 0) singleFound = 1; useDouble = 0; % use single precision %indEnd = findstr(line, ''); %doubleElement = line(indStart+12:indEnd-1); %if (strcmp(doubleElement,'yes')) % useDouble = 1; %elseif (strcmp(doubleElement,'no')) % useDouble = 0; %end end % look for tag, and work out how many moment groups there are % and their parameters (ie 1 or 0) if (~isempty(findstr(line,'')) & samplesFound ==0) samplesFound = 1; indStart = findstr(line, ''); indEnd = findstr(line, ''); samplesElement = line(indStart+9:indEnd-1); % remove spaces, then check the length of the string, if longer than % one, iterate over it finding values of moment groups samplesElement = strrep(samplesElement,' ',''); samplesLen = length(samplesElement); % for some reason data is still kept even if one of the % samples variables is 0... Oh well, I'll just set % numMomentGroups to the length of the samplesElement then... numMomentGroups = samplesLen; % if (samplesLen == 1) % % don't need to do anything (I guess....) % numMomentGroups = 1; % elseif (samplesLen > 1) % % this is the number of '); numIndepVars = str2num(line(indStart+length(searchStr):indEnd-1)); % look for the variables, how many of them and their names searchStr = ''; while (isempty(findstr(line,searchStr))) line = fgetl(fp); end % grab the next line, it *should* be a tag line = fgetl(fp); indStart = findstr(line,''); indEnd = findstr(line,''); % get the number of variables numVars = str2num(line(indStart+5:indEnd-1)); % now grab the next line, it *should* be a ') & findstr(line,'"Text"')) % now, this line should be the variables, space delimited line = fgetl(fp); inds = findstr(line,' '); if (length(inds) ~= numVars) disp('Number of variable names found not equal to number of variables') disp('Exiting...'); return end indStart = 1; varNames = {}; for i = 1:length(inds) indEnd = inds(i)-1; if (indEnd == indStart) varNames(i).name = strcat(line(indStart:indEnd),'_',num2str(imoments)); elseif (indEnd > indStart) varNames(i).name = strcat(line(indStart:indEnd),'_',num2str(imoments)); else disp('For some reason, indEnd is less than indStart') disp('Exiting...') return end indStart = inds(i)+1; end else disp('huh, for some reason I could not find a tag with "Text" field') end % now go looking for the data while(isempty(findstr(line,' or % loop until I find the stream line = fgetl(fp); i = 1; while(isempty(findstr(line,''))) indStart = findstr(line,''); indEnd = findstr(line,''); loopInd(i) = str2num(line(indStart+5:indEnd-1)); i = i + 1; line = fgetl(fp); end % ok, this line should tell me if the output was binary or text % however, I should already know (maybe I should error check....) if (useBinary) disp('loading binary file') % the line just read tells us if we are using % bigendian or littleendian binary format if(~isempty(findstr(line,'BigEndian'))) machineFormat = 'ieee-be'; elseif(~isempty(findstr(line,'LittleEndian'))) machineFormat = 'ieee-le'; else machineFormat = 'native'; end % the line also contains info about 64-bit integers if (~isempty(findstr(line,'uint64'))) UnsignedLong = 'uint64'; else UnsignedLong = 'ulong'; end % right, it's binary, now run the binary loading routine % this is the binary data filename line = fgetl(fp); % strip superfluous spaces... datFname = strrep(line,' ',''); % set the precison if (useDouble == 0) precision = 'single'; disp('using single precision data') else precision = 'double'; disp('using double precision data') end evalStr = ''; evalStr = sprintf('%s%s\n',evalStr,'% open the binary data file for reading'); evalStr = sprintf('%s%s%s%s%s%s\n',evalStr,'fpDat = fopen(''',datFname,''',''r'',''',machineFormat,''');'); evalStr = sprintf('%s%s\n', evalStr, 'if (fpDat < 0)'); evalStr = sprintf('%s%s%s%s\n', evalStr, ' fprintf(''Cannot open binary data file: ',datFname,''')'); evalStr = sprintf('%s%s\n', evalStr, ' return'); evalStr = sprintf('%s%s\n', evalStr, 'end'); % now the time to be a little tricky for i = 1:numIndepVars indexStrArray(i) = cellstr(strcat('index',num2str(i))); end % now try and load the variables into memory % I'm automatically generating the string that needs to be evaluated by matlab % and then running eval on it. % first, create a string of the variables to be loaded (this saves shitloads % of time). subscriptArray = {}; varsStr = ''; indepVarsStr = ''; if (debug) fprintf('num independent vars = %d\n',numIndepVars); fprintf('num variables in total = %d\n',numVars); end for k = 1:numVars if (debug) fprintf('varNames(%d).name = %s\n',k,varNames(k).name); end if (k <= numIndepVars) indepVarsStr = sprintf('%s%s%s%s\n',indepVarsStr,varNames(k).name,'Len',' = fread(fpDat,1,UnsignedLong);'); indepVarsStr = sprintf('%s%s%s%s%s\n',indepVarsStr,varNames(k).name,' = fread(fpDat,',varNames(k).name,'Len,precision);'); elseif (k > numIndepVars) varsStr = sprintf('%s%s%s%s\n',varsStr,varNames(k).name,'Len',' = fread(fpDat,1,UnsignedLong);'); if (numIndepVars == 1) varsStr = sprintf('%s%s%s%s%s\n',varsStr,varNames(k).name,' = fread(fpDat,',varNames(1).name,'Len,precision);'); elseif (numIndepVars == 2) varsStr = sprintf('%s%s%s%s%s%s%s\n',varsStr,varNames(k).name,' = fread(fpDat,[',varNames(2).name,'Len,',varNames(1).name,'Len],precision);'); elseif (numIndepVars > 2) % now we need to create a multi-dimensional matrix, and this is harder to do... % we need to read in a matrix-sized (ie 2D) block at a time, and append this to the other dimensions % the number of independent variables determines the dimensions of the N-D matrix to produce % construct the for loop to loop over the third and subsequent dimensions for inumIndepVars = 1:numIndepVars-2 varsStr = sprintf('%s%s%s%s%s%s\n',varsStr,'for ',char(indexStrArray(inumIndepVars)),' = 1:',varNames(inumIndepVars).name,'Len'); end % generate the first part of the string, which is the array to be assigned into varsStr = sprintf('%s%s%s',varsStr,varNames(k).name,'(:,:,'); for inumIndepVars = 1:numIndepVars-2 varsStr = sprintf('%s%s',varsStr,char(indexStrArray(inumIndepVars))); % need to append a comma if not last index to append if (inumIndepVars ~= numIndepVars-2) varsStr = sprintf('%s%s',varsStr,','); end end % generate the fread statement varsStr = sprintf('%s%s%s%s%s%s\n',varsStr,') = fread(fpDat,[',varNames(numIndepVars).name,'Len,',varNames(numIndepVars-1).name,'Len],precision);'); % finish off the for loop for inumIndepVars = 1:numIndepVars-2 varsStr = sprintf('%s%s\n',varsStr,'end'); end % disp('Error:') % disp('The number of independent variables is greater than 2') % disp('Unfortunately, loadxsil cannot yet handle this situation with binary data') % disp('Please use ascii data and the xsil2graphics utility program bundled with xmds') %return; % %%% the following code is for reference only, not to be used!!! % varsStr = sprintf('%s%s%s',varsStr,varNames(k).name,' = fread(fpDat,['); % for l = numIndepVars:-1:2 % we need to go backwards % varsStr = sprintf('%s%s%s',varsStr,varNames(l).name,'Len,'); % end % % now add the line that doesn't have the sepatating comma at the end % varsStr = sprintf('%s%s%s',varsStr,varNames(1).name,'Len'); % % and complete the string % varsStr = sprintf('%s%s\n',varsStr,'],precision);'); % %%% end of reference code end end end % now generate the string to evaluate evalStr = sprintf('%s%s',evalStr,indepVarsStr); evalStr = sprintf('%s%s',evalStr,varsStr); % remember to close the binary file evalStr = sprintf('%s%s\n',evalStr, 'fclose(fpDat);'); if (debug) disp(' ') disp('This is the string to be evaluated:') disp(' ') disp(evalStr) if (debug == 2) return end end % and evaluate it eval(evalStr) % assign output variables for i = 1:numVars assignin('caller',varNames(i).name,eval(varNames(i).name)); end % clean up and return if (imoments == numMomentGroups) fclose(fp); disp('done!') return end else % well, it's text, so now call the text loading routine disp('loading ascii data (this may take a while)') % now the time to be a little tricky for i = 1:numIndepVars indexStrArray(i) = cellstr(strcat('index',num2str(i))); end % now try and load the variables into memory % I'm automatically generating the string that needs to be evaluated by matlab % and then running eval on it. % first, create a string of the variables to be loaded (this saves shitloads % of time). subscriptArray = {}; % make the fscanf %e bit at the front of the string varsStr = 'A = fscanf(fp,'''; for k = 1:numVars varsStr = sprintf('%s%s',varsStr,'%e '); end varsStr = sprintf('%s%s%s%s\n',varsStr,''',',num2str(numVars),');'); for k = 1:numVars if (k <= numIndepVars) indexStr = strcat('(',char(indexStrArray(k)),')'); subscriptArray(k) = cellstr(indexStr); elseif (k > numIndepVars) indexStr = strcat('(',char(indexStrArray(1))); for j = 2:numIndepVars indexStr = strcat(indexStr,',',char(indexStrArray(j))); end indexStr = strcat(indexStr,')'); subscriptArray(k) = cellstr(indexStr); end varsStr = sprintf('%s%s%s%s%s%s\n',varsStr,varNames(k).name,char(subscriptArray(k)),' = A(',num2str(k),');'); end % now generate the string for preallocation preStr = ''; for k = 1:numVars if (k <= numIndepVars) indexStr = strcat('(',num2str(loopInd(k)),',1)'); subscriptArray(k) = cellstr(indexStr); elseif (k > numIndepVars) indexStr = strcat('(',num2str(loopInd(1))); for j = 2:numIndepVars indexStr = strcat(indexStr,',',num2str(loopInd(j))); end indexStr = strcat(indexStr,')'); subscriptArray(k) = cellstr(indexStr); end preStr = sprintf('%s%s%s%s%s\n',preStr,varNames(k).name,' = zeros',char(subscriptArray(k)),';'); end % now generate the string to evaluate evalStr = ''; for i = 1:numIndepVars evalStr = sprintf('%s%s%s%s%s\n',evalStr,'for ',char(indexStrArray(i)),' = 1:',num2str(loopInd(i))); if (i == 1) evalStr = sprintf('%s%s%s%s%s%s\n',evalStr,'if (rem(',char(indexStrArray(i)),',',num2str(loopInd(i)/10),') < 1)'); evalStr = sprintf('%s%s%s%s%s%s\n',evalStr,'fprintf(''%3.0f%% completed\n'',',char(indexStrArray(i)),'*100/',num2str(loopInd(i)),')'); evalStr = sprintf('%s%s\n',evalStr,'end'); end end evalStr = sprintf('%s%s',evalStr,varsStr); for i = 1:numIndepVars evalStr = sprintf('%s%s\n',evalStr,'end'); end if (debug) disp(evalStr); else % and evaluate it eval(evalStr); end % assign output variables for i = 1:numVars assignin('caller',varNames(i).name,eval(varNames(i).name)); end % clean up and return if (imoments == numMomentGroups) fclose(fp); disp('done!') return end end end end fclose(fp); return