function affystruct = affyread(filename,libdir)
%AFFYREAD reads Affymetrix GeneChip data files.
%
%   AFFYDATA = AFFYREAD(FILE) reads the Affymetrix data file, FILE, and
%   creates a structure, AFFYDATA. AFFYREAD can read DAT, EXP, CEL, CHP,
%   CDF and GIN files.
%
%   AFFYDATA = AFFYREAD(FILE,LIBDIR) allows you to specify the directory
%   where the library (CDF and GIN) files are stored.
%
%   Example:
%
%       % Read in a CEL file
%       celStruct = affyread('Drosophila-121502.CEL')
%       % Display a spatial plot of probe intensities
%       maimage(celStruct,'Intensity');
%
%       % Read in a DAT file and display the raw image data
%       datStruct = affyread('Drosophila-121502.dat')
%       imagesc(datStruct.Image);
%       axis image;
%
%       % Read in a CHP file and plot the probe values for probe set 143417_at
%       % Note the CHP files require the library files. Your file may be in
%       % a different location.
%       chpStruct = affyread('Drosophila-121502.chp',...
%                                  'D:\Affymetrix\LibFiles\DrosGenome1')
%       geneName = probesetlookup(chpStruct,'143417_at')
%       probesetplot(chpStruct,'143417_at');
%
%   Sample data files are available from
%   http://www.affymetrix.com/support/technical/sample_data/demo_data.affx
%
%   See also GPRREAD, PROBELIBRARYINFO, PROBESETLINK, PROBESETLOOKUP, 
%   PROBESETPLOT, PROBESETVALUES, SPTREAD.
%
%   GeneChip and Affymetrix are registered trademarks of Affymetrix, Inc.

% Copyright 2003-2004 The MathWorks, Inc.
% $Revision: 1.1.6.7 $   $Date: 2004/12/24 20:44:06 $

% Currently only supported on Windows
if ~ispc
    error('Bioinfo:affyread:AffyreadWindowsOnly',...
        'AFFYREAD is only supported on Windows.');
end

if nargin < 1
    error('Bioinfo:affyread:NotEnoughInputs',...
        'Not enough input arguments.');
end

% The GDAC runtime libraries must be installed. Check to see if they are.
% If not try to install them.
try
    % first see if the files are on the path, then try the registry
    if isempty(strfind(lower(getenv('PATH')),'gdacfiles'))
    verNum  = winqueryreg('HKEY_LOCAL_MACHINE',...
        'SOFTWARE\Affymetrix\GDAC', 'GDACFiles Version'); %#ok
    end
catch
    % GDAC runtime not installed...
    theButton =questdlg(...
        sprintf(['The Affymetrix GDAC Runtime Libraries must be installed. \n',...
        'Would you like to install them now?']),...
        'Install GDAC Runtime Libraries?',...
        'Yes','No','Yes');
    if strcmp(theButton,'Yes')
        system([matlabroot '\toolbox\bioinfo\microarray\lib\GDACFilesInstall.exe']);
    else
        error('Bioinfo:affyread:GDACNotInstalled',...
            'Affyread requires the Affymetrix GDAC Runtime Libraries.');
    end
end

% figure out if the file is in the current directory of not
[pathdir,theName,theExt] = fileparts(filename);

% if no path part, use the local directory
if isempty(pathdir)
    pathdir = pwd;
end

% check for valid extensions?
theFile = [theName,upper(theExt)];

% Set up the lib path
if nargin == 1
    libdir = pathdir;
end
fullpath = [pathdir,filesep,theFile];
if ~exist(fullpath,'file')
    % try libdir
    fullpath = [libdir,filesep,theFile];
    if ~exist(fullpath,'file')
        error('Bioinfo:affyread:FileDoesNotExist',...
            '%s does not appear to exist.',theFile);
    else
        pathdir = libdir;
    end
end

% if libdir points to a file then use its directory
if ~exist(libdir,'dir') && exist(libdir,'file')
    libdir = fileparts(libdir);
end

% check that libdir exists
if ~exist(libdir,'dir')
    warning('Bioinfo:affyread:LibdirNotDirectory',...
        '%s does not appear to be a directory.',libdir);
elseif isempty(dir([libdir,filesep,'*.cdf']))
    if strcmpi(theExt,'.chp')
        warning('Bioinfo:affyread:NoCDFInLibdir',...
            '%s does not contain any library (CDF) files.',libdir);
    end
end

% read the file using affymex
if ~strcmpi(theExt,'.gin')
    affystruct = affymex(theFile,pathdir,libdir);
else
    affystruct = affyginread(filename,pathdir,libdir);
end
if isempty(affystruct)
    error('Bioinfo:affyread:AffymexFailed','Unable to read file %s.',theFile);
end


function ginStruct = affyginread(filename,pathdir,libdir) %#ok
% AFFYGINREAD reads in GIN files that contain gene identifiers
fullFileName = '';
if exist(filename,'file')
    % we have the file
    fullFileName = filename;
else
    if nargin > 1
        fullFileName = fullfile(libdir,filename);
    end
end

fid = fopen(fullFileName,'r');
if fid < 0
    error('Bioinfo:affyread:BadFile',...
        'Cannot open file %s',fullFileName);
end
% Read in the header lines
line = fgetl(fid);
version = strread(line,'%*s%d','delimiter','=');
line = fgetl(fid);
name = strread(line,'%*s%s','delimiter','=');
line = fgetl(fid);
numURLs = strread(line,'%*s%d','delimiter','=');

% allocate space for the references and URLS.
urls = cell(numURLs,1);
refname = cell(numURLs,1);%#ok
refs = cell(numURLs,1);
for count = 1: numURLs
    line = fgetl(fid);
    [refs(count) , refname(count), urls(count)] =...
        strread(line,'%s%s%s','delimiter',';');%#ok
end

% Read in the rest of the file skipping the line with column headings.
out = textscan(fid,'%d%s%s%s%s%*[^\n]','headerlines',1,'delimiter','\t');
% close the file
fclose(fid);

% Set output structure
ginStruct.Name = name{:};
ginStruct.Version = version;
ginStruct.ProbeSetName = out{:,4};
ginStruct.ID = out{:,2};
ginStruct.Description = out{:,5};
if numURLs == 1
    ginStruct.SourceNames = refs{:};
    ginStruct.SourceURL = urls{:};
    ginStruct.SourceID = 1;
else
    ginStruct.SourceNames = refs;
    ginStruct.SourceURL = urls;
    [dummy, ginStruct.SourceID ] = ismember(out{:,3}, refs);%#ok
end
