function probesetplot(chpStruct,theID,varargin)
% PROBESETPLOT plots values for an Affymetrix CHP file probe set
%
%   PROBESETPLOT(CHPStruct,ID) plots the PM and MM intensity values for
%   probe set ID. CHPStruct is a structure created from an Affymetrix CHP
%   file. ID can be the index of the probe set or the probe set name. Note
%   that the probe set numbers for a CHP file use 0-based indexing, whereas
%   MATLAB uses 1-based indexing. CHPStruct.ProbeSets(1) has ProbeSetNumber
%   0. 
%
%   PROBESETPLOT(...,'GENENAME',true) uses the gene name, rather than
%   probe set name, for the title. 
%
%   PROBESETPLOT(...,'FIELD',FIELDNAME) shows the data for the field
%   FIELDNAME. Valid field names are Background, Intensity, StdDev,
%   Pixels, Outlier.
%
%   PROBESETPLOT(...,'SHOWSTATS',true) adds mean and standard deviation
%   lines to the plot.
%
%   Example:
%       chpStruct = affyread('Drosophila-121502.chp',...
%                                  'D:\Affymetrix\LibFiles\DrosGenome1')
%       probesetplot(chpStruct,'AFFX-YEL018w/_at','showstats',true);
%
%   See also AFFYREAD, PROBESETLINK, PROBESETLOOKUP.

%   Affymetrix is a registered trademarks of Affymetrix, Inc.

% Copyright 2003-2004 The MathWorks, Inc.
% $Revision: 1.1.12.1 $   $Date: 2004/12/24 20:45:00 $



% Set defaults
fieldNames = { 'Background',...
    'Intensity',...
    'StdDev',...
    'Pixels',...
    'Outlier',...
    'Masked'};

fieldNamesMapping = {'ProbeSetNumber',...
    'ProbePairNumber',...
    'UseProbePair',...
    'Background',...
    'PMPosX',...
    'PMPosY',...
    'PMIntensity',...
    'PMStdDev',...
    'PMPixels',...
    'PMOutlier',...
    'PMMasked',...
    'MMPosX',...
    'MMPosY',...
    'MMIntensity',...
    'MMStdDev',...
    'MMPixels',...
    'MMOutlier',...
    'MMMasked'};

legendFieldNames =    {'Probe Set Number',...
    'Probe Pair Number',...
    'Use Probe Pair',...
    'Background',...
    'Perfect Match PosX',...
    'Perfect Match PosY',...
    'Perfect Match Intensity',...
    'Perfect Match StdDev',...
    'Perfect Match Pixels',...
    'Perfect Match Outlier',...
    'Perfect Match Masked',...
    'Mismatch PosX',...
    'Mismatch PosY',...
    'Mismatch Intensity',...
    'Mismatch StdDev',...
    'Mismatch Pixels',...
    'Mismatch Outlier',...
    'Mismatch Masked'};
fieldNum = 2;
PMfieldNum = 7;
MMfieldNum = 14;
statsFlag = false;
backgroundFlag = false;
genenameFlag = false;
% get the ID
if ischar(theID)
    ID = strmatch(theID,{chpStruct.ProbeSets.Name});%#ok
    if isempty(ID)
        error('Bioinfo:UnknownProbeName',...
            'Unknown probe set name: %s.',theID);
    elseif length(ID)>1
        warning('Bioinfo:AmbiguousParameterName',...
            'Ambiguous probe set name: %s.',theID);
        ID = ID(1);
    end
else
    ID = theID;
end

% deal with the various inputs
if nargin > 2
    if rem(nargin,2) == 1
        error('Bioinfo:IncorrectNumberOfArguments',...
            'Incorrect number of arguments to %s.',mfilename);
    end
    okargs = {'fieldname','showstats','genename'};
    for j=1:2:nargin-2
        pname = varargin{j};
        pval = varargin{j+1};
        k = strmatch(lower(pname), okargs);%#ok
        if isempty(k)
            error('Bioinfo:UnknownParameterName',...
                'Unknown parameter name: %s.',pname);
        elseif length(k)>1
            error('Bioinfo:AmbiguousParameterName',...
                'Ambiguous parameter name: %s.',pname);
        else
            switch(k)
                case 1  % field
                    if ischar(pval)
                        fieldNum = find(strncmpi(pval,fieldNames,length(pval)));
                        if isempty(fieldNum)
                            error('Bioinfo:UnknownFieldName',...
                                'Unknown field name: %s.',pval);
                        elseif length(fieldNum)>1
                            error('Bioinfo:UnknownFieldName',...
                                'Ambiguous field name: %s.',pval);
                        end
                        if fieldNum == 1  % background is a special case
                            backgroundFlag = true;
                            PMfieldNum = find(strncmpi(pval,fieldNamesMapping,length(pval)));
                        else
                            PMfieldNum = find(strncmpi(['PM' pval],fieldNamesMapping,length(pval)));
                            MMfieldNum = find(strncmpi(['MM' pval],fieldNamesMapping,length(pval)));
                        end
                    else
                        error('Bioinfo:BadFieldName',...
                            'Field name must be a string.');
                    end
                case 2 % showStats
                    statsFlag = opttf(pval);
                    if isempty(statsFlag)
                        error('Bioinfo:InputOptionNotLogical','%s must be a logical value, true or false.',...
                            upper(char(okargs(k))));
                    end
                case 3 % genename
                    genenameFlag = opttf(pval);
                    if isempty(genenameFlag)
                        error('Bioinfo:InputOptionNotLogical','%s must be a logical value, true or false.',...
                            upper(char(okargs(k))));
                    end
            end
        end
    end
end

% Extract the data from the big struct
theSet = chpStruct.ProbeSets(ID).ProbePairs;
if ~genenameFlag
    theName = chpStruct.ProbeSets(ID).Name;
else
    theName = probesetlookup(chpStruct,chpStruct.ProbeSets(ID).Name);
end
% Everything is zero based, so add one -- hopefully this won't confuse
% anyone. Li & Wong do this
xData = theSet(:,2)+1;

% plot the PM data
hPlot = plot(xData,theSet(:,PMfieldNum),'marker','x','markersize',10);
hold on
legendString = {legendFieldNames{PMfieldNum}};
if ~backgroundFlag % plot the mismatch data
    hPlot = plot(xData,theSet(:,MMfieldNum),'r','marker','x','markersize',10);
    legendString = {legendString{:} legendFieldNames{MMfieldNum}};
end

hAxis = get(hPlot,'parent');
% Add labels and ticks
set(hAxis,'xtick',xData,'xlim',[0 max(xData)+1],...
    'xticklabel',num2str(xData));
title(sprintf('%s %s',theName,fieldNames{fieldNum}),...
    'interpreter','none');
xlabel('Probe Pair')
ylabel(fieldNames{fieldNum});

% Add on the mean and std and a legend
if statsFlag
    xData = [0;xData;xData(end)+1];
    rep = ones(size(xData));
    mVal = nanmean(theSet(:,PMfieldNum));
    plot(xData,mVal(rep),'k-.');
    stdVal = nanstd(theSet(:,PMfieldNum));
    plusOne = mVal + stdVal;
    minusOne = mVal - stdVal;
    plot([xData;NaN;xData],[plusOne(rep);NaN;minusOne(rep)],'m-.');
    % display mismatch stats
    if backgroundFlag
        legendString =  {legendString{:} ,'Mean','STD'};
    else
        mVal = nanmean(theSet(:,MMfieldNum));
        plot(xData,mVal(rep),'c-.');
        stdVal = nanstd(theSet(:,MMfieldNum));
        plusOne = mVal + stdVal;
        minusOne = mVal - stdVal;
        plot([xData;NaN;xData],[plusOne(rep);NaN;minusOne(rep)],'g-.');
        legendString =  {legendString{:} ,'PM Mean','PM STD','MM Mean','MM STD'};
    end
end
hold off
legend(legendString);