Home > RAVEN > addMets.m

addMets

PURPOSE ^

addMets

SYNOPSIS ^

function newModel=addMets(model,metsToAdd,copyInfo)

DESCRIPTION ^

 addMets
   Adds metabolites to a model

   model        a model structure
   metsToAdd    the metabolite structure can have the following fields:
                mets           cell array with unique strings that 
                               identifies each metabolite (opt, default is
                               that new metabolites that are added will be
                               assigned IDs "m1", "m2"... If IDs on the same
                               form are already used in the model then the
                               numbering will start from the highest existing
                               integer+1)
                metNames       cell array with the names of each
                               metabolite
                compartments   cell array with the compartment of each
                               metabolite. Should match model.comps.
                               If this is a string rather than a cell
                               array it is assumed that all mets are in
                               that compartment
                b              Nx1 or Nx2 matrix with equality constraints
                               for each metabolite (opt, default 0)
                unconstrained  vector describing if each metabolite is an
                               exchange metabolite (1) or not (0) (opt,
                               default 0)
                inchis         cell array with InChI strings for each
                               metabolite (opt, default '')
                metFormulas    cell array with the formulas for each of
                               the metabolites (opt, default '')
                metMiriams     cell array with MIRIAM structures (opt,
                               default [])
   copyInfo     when adding metabolites to a compartment where it previously
                doesn't exist, the function will copy any available annotation 
                from the metabolite in another compartment (opt, default true)

   newModel     an updated model structure

   NOTE: This function does not make extensive checks about MIRIAM formats,
   forbidden characters or such.

   Usage: newModel=addMets(model,metsToAdd,copyInfo)

   Rasmus Agren, 2013-02-06

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function newModel=addMets(model,metsToAdd,copyInfo)
0002 % addMets
0003 %   Adds metabolites to a model
0004 %
0005 %   model        a model structure
0006 %   metsToAdd    the metabolite structure can have the following fields:
0007 %                mets           cell array with unique strings that
0008 %                               identifies each metabolite (opt, default is
0009 %                               that new metabolites that are added will be
0010 %                               assigned IDs "m1", "m2"... If IDs on the same
0011 %                               form are already used in the model then the
0012 %                               numbering will start from the highest existing
0013 %                               integer+1)
0014 %                metNames       cell array with the names of each
0015 %                               metabolite
0016 %                compartments   cell array with the compartment of each
0017 %                               metabolite. Should match model.comps.
0018 %                               If this is a string rather than a cell
0019 %                               array it is assumed that all mets are in
0020 %                               that compartment
0021 %                b              Nx1 or Nx2 matrix with equality constraints
0022 %                               for each metabolite (opt, default 0)
0023 %                unconstrained  vector describing if each metabolite is an
0024 %                               exchange metabolite (1) or not (0) (opt,
0025 %                               default 0)
0026 %                inchis         cell array with InChI strings for each
0027 %                               metabolite (opt, default '')
0028 %                metFormulas    cell array with the formulas for each of
0029 %                               the metabolites (opt, default '')
0030 %                metMiriams     cell array with MIRIAM structures (opt,
0031 %                               default [])
0032 %   copyInfo     when adding metabolites to a compartment where it previously
0033 %                doesn't exist, the function will copy any available annotation
0034 %                from the metabolite in another compartment (opt, default true)
0035 %
0036 %   newModel     an updated model structure
0037 %
0038 %   NOTE: This function does not make extensive checks about MIRIAM formats,
0039 %   forbidden characters or such.
0040 %
0041 %   Usage: newModel=addMets(model,metsToAdd,copyInfo)
0042 %
0043 %   Rasmus Agren, 2013-02-06
0044 %
0045 
0046 if nargin<3
0047    copyInfo=true; 
0048 end
0049 
0050 newModel=model;
0051 
0052 if isempty(metsToAdd)
0053     return;
0054 end
0055 
0056 %Check some stuff regarding the required fields
0057 if ~isfield(metsToAdd,'mets')
0058     %Name the metabolites as "m1, m2...". If IDs on the same form are already
0059     %used in the model then the first available integers should be used
0060     maxCurrent=ceil(max(cellfun(@getInteger,model.mets)));
0061     m=maxCurrent+1:maxCurrent+numel(metsToAdd.metNames);
0062     metsToAdd.mets=strcat({'m'},num2str(m(:)));
0063 end
0064 if ~isfield(metsToAdd,'metNames')
0065     throw(MException('','metNames is a required field in metsToAdd'));
0066 end
0067 if ~isfield(metsToAdd,'compartments')
0068     throw(MException('','compartments is a required field in metsToAdd'));
0069 end
0070 
0071 if ~iscellstr(metsToAdd.mets)
0072     throw(MException('','metsToAdd.mets must be a cell array of strings'));
0073 end
0074 if ~iscellstr(metsToAdd.metNames)
0075     throw(MException('','metsToAdd.metNames must be a cell array of strings'));
0076 end
0077 if ~iscellstr(metsToAdd.compartments)
0078     if ischar(metsToAdd.compartments)
0079         temp=cell(numel(metsToAdd.mets),1);
0080         temp(:)={metsToAdd.compartments};
0081         metsToAdd.compartments=temp;
0082     else
0083         throw(MException('','metsToAdd.compartments must be a cell array of strings'));
0084     end
0085 end
0086 
0087 %Number of metabolites
0088 nMets=numel(metsToAdd.mets);
0089 nOldMets=numel(model.mets);
0090 filler=cell(nMets,1);
0091 filler(:)={''};
0092 largeFiller=cell(nOldMets,1);
0093 largeFiller(:)={''};
0094 
0095 %Check that no metabolite ids are already present in the model
0096 I=ismember(metsToAdd.mets,model.mets);
0097 if any(I)
0098     throw(MException('','One or more elements in metsToAdd.mets are already present in model.mets'));
0099 else
0100     newModel.mets=[newModel.mets;metsToAdd.mets(:)];
0101 end
0102 
0103 %Check that all the compartments could be found
0104 [I compMap]=ismember(metsToAdd.compartments,model.comps);
0105 if ~all(I)
0106     throw(MException('','metsToAdd.compartments must match model.comps'));
0107 end
0108 
0109 %Check that the metabolite names aren't present in the same compartment.
0110 %Not the neatest way maybe..
0111 t1=strcat(metsToAdd.metNames(:),'¤¤¤',metsToAdd.compartments(:));
0112 t2=strcat(model.metNames,'¤¤¤',model.comps(model.metComps));
0113 if any(ismember(t1,t2))
0114     throw(MException('','One or more elements in metsToAdd.metNames already exist in the same compartments as the one it is being added to'));
0115 end
0116 
0117 %Some more checks and if they pass then add each field to the structure
0118 if numel(metsToAdd.metNames)~=nMets
0119    throw(MException('','metsToAdd.metNames must have the same number of elements as metsToAdd.mets'));
0120 else
0121     newModel.metNames=[newModel.metNames;metsToAdd.metNames(:)];
0122 end
0123 
0124 if numel(compMap)~=nMets
0125    throw(MException('','metsToAdd.compartments must have the same number of elements as metsToAdd.mets'));
0126 else
0127     newModel.metComps=[newModel.metComps;compMap];
0128 end
0129 
0130 if isfield(metsToAdd,'b')
0131    if size(metsToAdd.b,1)~=nMets
0132        throw(MException('','metsToAdd.b must have the same number of elements as metsToAdd.mets'));
0133    else
0134        %Add empty field if it doesn't exist
0135        if ~isfield(newModel,'b')
0136             newModel.b=zeros(nOldMets,1);
0137        end
0138        
0139        %If the original is only one vector
0140        if size(metsToAdd.b,2)>size(newModel.b,2)
0141            newModel.b=[newModel.b newModel.b];
0142        end
0143        %Add the new ones
0144        newModel.b=[newModel.b;metsToAdd.b];
0145    end
0146 else
0147     if isfield(newModel,'b')
0148         %Add the default
0149         newModel.b=[newModel.b;zeros(nMets,size(newModel.b,2))];
0150     end
0151 end
0152 
0153 if isfield(metsToAdd,'unconstrained')
0154    if numel(metsToAdd.unconstrained)~=nMets
0155        throw(MException('','metsToAdd.unconstrained must have the same number of elements as metsToAdd.mets'));
0156    else
0157        %Add empty field if it doesn't exist
0158        if ~isfield(newModel,'unconstrained')
0159             newModel.unconstrained=zeros(nOldMets,1);
0160        end
0161        
0162        %Add the new ones
0163        newModel.unconstrained=[newModel.unconstrained;metsToAdd.unconstrained(:)];
0164    end
0165 else
0166     if isfield(newModel,'unconstrained')
0167         %Add the default
0168         newModel.unconstrained=[newModel.unconstrained;zeros(nMets,1)];
0169     end
0170 end
0171 
0172 if isfield(metsToAdd,'inchis')
0173    if numel(metsToAdd.inchis)~=nMets
0174        throw(MException('','metsToAdd.inchis must have the same number of elements as metsToAdd.mets'));
0175    end
0176    if ~iscellstr(metsToAdd.inchis)
0177         throw(MException('','metsToAdd.inchis must be a cell array of strings'));
0178    end
0179    %Add empty field if it doesn't exist
0180    if ~isfield(newModel,'inchis')
0181         newModel.inchis=largeFiller;
0182    end
0183    newModel.inchis=[newModel.inchis;metsToAdd.inchis(:)];
0184 else
0185     %Add empty strings if structure is in model
0186     if isfield(newModel,'inchis')
0187        newModel.inchis=[newModel.inchis;filler];
0188     end
0189 end
0190 
0191 if isfield(metsToAdd,'metFormulas')
0192    if numel(metsToAdd.metFormulas)~=nMets
0193        throw(MException('','metsToAdd.metFormulas must have the same number of elements as metsToAdd.mets'));
0194    end
0195    if ~iscellstr(metsToAdd.metFormulas)
0196         throw(MException('','metsToAdd.metFormulas must be a cell array of strings'));
0197    end
0198    %Add empty field if it doesn't exist
0199    if ~isfield(newModel,'metFormulas')
0200         newModel.metFormulas=largeFiller;
0201    end
0202    newModel.metFormulas=[newModel.metFormulas;metsToAdd.metFormulas(:)];
0203 else
0204     %Add default
0205     if isfield(newModel,'metFormulas')
0206        newModel.metFormulas=[newModel.metFormulas;filler]; 
0207     end
0208 end
0209 
0210 %Don't check the type of metMiriams
0211 if isfield(metsToAdd,'metMiriams')
0212    if numel(metsToAdd.metMiriams)~=nMets
0213        throw(MException('','metsToAdd.metMiriams must have the same number of elements as metsToAdd.mets'));
0214    end
0215    %Add empty field if it doesn't exist
0216    if ~isfield(newModel,'metMiriams')
0217         newModel.metMiriams=cell(nOldMets,1);
0218    end
0219    newModel.metMiriams=[newModel.metMiriams;metsToAdd.metMiriams(:)]; 
0220 else
0221     if isfield(newModel,'metMiriams')
0222        newModel.metMiriams=[newModel.metMiriams;cell(nMets,1)]; 
0223     end
0224 end
0225 
0226 if isfield(newModel,'metFrom')
0227     newModel.metFrom=[newModel.metFrom;filler];
0228 end
0229 
0230 %Expand the S matrix
0231 newModel.S=[newModel.S;sparse(nMets,size(newModel.S,2))];
0232 
0233 if copyInfo==true
0234    [I J]=ismember(metsToAdd.metNames,model.metNames);
0235    J=J(I);
0236    %I is the indexes of the new metabolites for which a metabolite with the
0237    %same name existed
0238    I=find(I)+nOldMets;
0239    %Go through each of the added mets and copy annotation if it doesn't exist
0240    for i=1:numel(I)
0241        if isfield(newModel,'inchis')
0242            if isempty(newModel.inchis{I(i)})
0243                newModel.inchis(I(i))=newModel.inchis(J(i));
0244            end
0245        end
0246        if isfield(newModel,'metFormulas')
0247            if isempty(newModel.metFormulas{I(i)})
0248                newModel.metFormulas(I(i))=newModel.metFormulas(J(i));
0249            end
0250        end
0251        if isfield(newModel,'metMiriams')
0252            if isempty(newModel.metMiriams{I(i)})
0253                newModel.metMiriams(I(i))=newModel.metMiriams(J(i));
0254            end
0255        end
0256    end
0257 end
0258 end
0259 %For getting the numerical form of metabolite ids on the form "m1".
0260 function I=getInteger(s)
0261     %Checks if a string is on the form "m1" and if so returns the value of
0262     %the integer
0263     I=0;
0264     if strcmpi(s(1),'m')
0265         t=str2double(s(2:end));
0266         if ~isnan(t) && ~isempty(t)
0267             I=t;
0268         end
0269     end
0270 end

Generated on Tue 23-Apr-2013 15:18:37 by m2html © 2005