Home > core > addMets.m

addMets

PURPOSE ^

addMets

SYNOPSIS ^

function newModel=addMets(model,metsToAdd,copyInfo,prefix)

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 IDs
                              of new metabolites are numbered with the
                              prefix defined below)
               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 '')
               metSmiles      cell array with SMILES 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 [])
               metCharges     metabolite charge (opt, default NaN)
               metDeltaG      Gibbs free energy of formation at
                              biochemical standard condition in kJ/mole
                              (opt, default NaN)
               metNotes       cell array with metabolite notes as strings
                              (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)
   prefix      when metsToAdd.mets is not specified, new metabolite IDs
               are generated with the prefix specified here. If IDs with
               the prefix are already used in the model then the
               numbering will start from the highest existing integer+1
               (opt, default 'm_')

   newModel     an updated model structure

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

   Example: If multiple metabolites are added at once, the metMiriams cell
   array should be defined as (example with ChEBI and KEGG):

   metsToAdd.metMiriams{1} = struct('name',{{'chebi';'kegg.compound'}},...
       'value',{{'CHEBI:18072';'C11821'}});
   metsToAdd.metMiriams{2} = struct('name',{{'chebi';'kegg.compound'}},...
       'value',{{'CHEBI:31132';'C12248'}});

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

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function newModel=addMets(model,metsToAdd,copyInfo,prefix)
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 IDs
0009 %                              of new metabolites are numbered with the
0010 %                              prefix defined below)
0011 %               metNames       cell array with the names of each
0012 %                              metabolite
0013 %               compartments   cell array with the compartment of each
0014 %                              metabolite. Should match model.comps.
0015 %                              If this is a string rather than a cell
0016 %                              array it is assumed that all mets are in
0017 %                              that compartment
0018 %               b              Nx1 or Nx2 matrix with equality constraints
0019 %                              for each metabolite (opt, default 0)
0020 %               unconstrained  vector describing if each metabolite is an
0021 %                              exchange metabolite (1) or not (0) (opt,
0022 %                              default 0)
0023 %               inchis         cell array with InChI strings for each
0024 %                              metabolite (opt, default '')
0025 %               metSmiles      cell array with SMILES strings for each
0026 %                              metabolite (opt, default '')
0027 %               metFormulas    cell array with the formulas for each of
0028 %                              the metabolites (opt, default '')
0029 %               metMiriams     cell array with MIRIAM structures (opt,
0030 %                              default [])
0031 %               metCharges     metabolite charge (opt, default NaN)
0032 %               metDeltaG      Gibbs free energy of formation at
0033 %                              biochemical standard condition in kJ/mole
0034 %                              (opt, default NaN)
0035 %               metNotes       cell array with metabolite notes as strings
0036 %                              (opt, default '')
0037 %   copyInfo    when adding metabolites to a compartment where it previously
0038 %               doesn't exist, the function will copy any available annotation
0039 %               from the metabolite in another compartment (opt, default true)
0040 %   prefix      when metsToAdd.mets is not specified, new metabolite IDs
0041 %               are generated with the prefix specified here. If IDs with
0042 %               the prefix are already used in the model then the
0043 %               numbering will start from the highest existing integer+1
0044 %               (opt, default 'm_')
0045 %
0046 %   newModel     an updated model structure
0047 %
0048 %   NOTE: This function does not make extensive checks about MIRIAM formats,
0049 %   forbidden characters or such.
0050 %
0051 %   Example: If multiple metabolites are added at once, the metMiriams cell
0052 %   array should be defined as (example with ChEBI and KEGG):
0053 %
0054 %   metsToAdd.metMiriams{1} = struct('name',{{'chebi';'kegg.compound'}},...
0055 %       'value',{{'CHEBI:18072';'C11821'}});
0056 %   metsToAdd.metMiriams{2} = struct('name',{{'chebi';'kegg.compound'}},...
0057 %       'value',{{'CHEBI:31132';'C12248'}});
0058 %
0059 %   Usage: newModel=addMets(model,metsToAdd,copyInfo,prefix)
0060 
0061 if nargin<3
0062     copyInfo=true;
0063 end
0064 if nargin<4
0065     prefix='m_';
0066 else
0067     prefix=char(prefix);
0068 end
0069 
0070 newModel=model;
0071 
0072 if isempty(metsToAdd)
0073     return;
0074 end
0075 
0076 %Check some stuff regarding the required fields
0077 if ~isfield(metsToAdd,'mets')
0078     metsToAdd.mets=generateNewIds(newModel,'mets',prefix,numel(metsToAdd.metNames));
0079 else
0080     metsToAdd.mets=convertCharArray(metsToAdd.mets);
0081 end
0082 if ~isfield(metsToAdd,'metNames')
0083     metsToAdd.metNames=metsToAdd.mets;
0084 else
0085     metsToAdd.metNames=convertCharArray(metsToAdd.metNames);
0086 end
0087 if ~isfield(metsToAdd,'compartments')
0088     EM='compartments is a required field in metsToAdd';
0089     dispEM(EM);
0090 else
0091     metsToAdd.compartments=convertCharArray(metsToAdd.compartments);
0092     %If only one compartment is given, assume it is for all metabolites
0093     if numel(metsToAdd.compartments)==1 && numel(metsToAdd.mets)>1
0094         temp=cell(numel(metsToAdd.mets),1);
0095         temp(:)=metsToAdd.compartments;
0096         metsToAdd.compartments=temp;
0097     end
0098 end
0099 
0100 %Number of metabolites
0101 nMets=numel(metsToAdd.mets);
0102 nOldMets=numel(model.mets);
0103 filler=cell(nMets,1);
0104 filler(:)={''};
0105 largeFiller=cell(nOldMets,1);
0106 largeFiller(:)={''};
0107 
0108 %Check that no metabolite ids are already present in the model
0109 I=ismember(metsToAdd.mets,model.mets);
0110 if any(I)
0111     error('One or more elements in metsToAdd.mets are already present in model.mets: %s',...
0112         strjoin(metsToAdd.mets(I),', '));
0113 else
0114     newModel.mets=[newModel.mets;metsToAdd.mets(:)];
0115 end
0116 
0117 %Check that all the compartments could be found
0118 [I, compMap]=ismember(metsToAdd.compartments,model.comps);
0119 if ~all(I)
0120     EM='metsToAdd.compartments must match model.comps';
0121     dispEM(EM);
0122 end
0123 
0124 %Check that the metabolite names aren't present in the same compartment.
0125 %Not the neatest way maybe..
0126 t1=strcat(metsToAdd.metNames(:),'***',metsToAdd.compartments(:));
0127 t2=strcat(model.metNames,'***',model.comps(model.metComps));
0128 if any(ismember(t1,t2))
0129     EM='One or more elements in metsToAdd.metNames already exist in the same compartments as the one it is being added to';
0130     dispEM(EM);
0131 end
0132 
0133 %Some more checks and if they pass then add each field to the structure
0134 if numel(metsToAdd.metNames)~=nMets
0135     EM='metsToAdd.metNames must have the same number of elements as metsToAdd.mets';
0136     dispEM(EM);
0137 else
0138     newModel.metNames=[newModel.metNames;metsToAdd.metNames(:)];
0139 end
0140 
0141 if numel(compMap)~=nMets
0142     EM='metsToAdd.compartments must have the same number of elements as metsToAdd.mets';
0143     dispEM(EM);
0144 else
0145     newModel.metComps=[newModel.metComps;compMap(:)];
0146 end
0147 
0148 if isfield(metsToAdd,'b')
0149     if size(metsToAdd.b,1)~=nMets
0150         EM='metsToAdd.b must have the same number of elements as metsToAdd.mets';
0151         dispEM(EM);
0152     else
0153         %Add empty field if it doesn't exist
0154         if ~isfield(newModel,'b')
0155             newModel.b=zeros(nOldMets,1);
0156         end
0157         
0158         %If the original is only one vector
0159         if size(metsToAdd.b,2)>size(newModel.b,2)
0160             newModel.b=[newModel.b newModel.b];
0161         end
0162         %Add the new ones
0163         newModel.b=[newModel.b;metsToAdd.b];
0164     end
0165 else
0166     if isfield(newModel,'b')
0167         %Add the default
0168         newModel.b=[newModel.b;zeros(nMets,size(newModel.b,2))];
0169     end
0170 end
0171 
0172 if isfield(metsToAdd,'unconstrained')
0173     if numel(metsToAdd.unconstrained)~=nMets
0174         EM='metsToAdd.unconstrained must have the same number of elements as metsToAdd.mets';
0175         dispEM(EM);
0176     else
0177         %Add empty field if it doesn't exist
0178         if ~isfield(newModel,'unconstrained')
0179             newModel.unconstrained=zeros(nOldMets,1);
0180         end
0181         
0182         %Add the new ones
0183         newModel.unconstrained=[newModel.unconstrained;metsToAdd.unconstrained(:)];
0184     end
0185 else
0186     if isfield(newModel,'unconstrained')
0187         %Add the default
0188         newModel.unconstrained=[newModel.unconstrained;zeros(nMets,1)];
0189     end
0190 end
0191 
0192 if isfield(metsToAdd,'inchis')
0193     metsToAdd.inchis=convertCharArray(metsToAdd.inchis);
0194     if numel(metsToAdd.inchis)~=nMets
0195         EM='metsToAdd.inchis must have the same number of elements as metsToAdd.mets';
0196         dispEM(EM);
0197     end
0198     %Add empty field if it doesn't exist
0199     if ~isfield(newModel,'inchis')
0200         newModel.inchis=largeFiller;
0201     end
0202     newModel.inchis=[newModel.inchis;metsToAdd.inchis(:)];
0203 else
0204     %Add empty strings if structure is in model
0205     if isfield(newModel,'inchis')
0206         newModel.inchis=[newModel.inchis;filler];
0207     end
0208 end
0209 
0210 
0211 if isfield(metsToAdd,'metSmiles')
0212     metsToAdd.metSmiles=convertCharArray(metsToAdd.metSmiles);
0213     if numel(metsToAdd.metSmiles)~=nMets
0214         EM='metsToAdd.metSmiles must have the same number of elements as metsToAdd.mets';
0215         dispEM(EM);
0216     end
0217     %Add empty field if it doesn't exist
0218     if ~isfield(newModel,'metSmiles')
0219         newModel.metSmiles=largeFiller;
0220     end
0221     newModel.metSmiles=[newModel.metSmiles;metsToAdd.metSmiles(:)];
0222 else
0223     %Add empty strings if structure is in model
0224     if isfield(newModel,'metSmiles')
0225         newModel.metSmiles=[newModel.metSmiles;filler];
0226     end
0227 end
0228 
0229 if isfield(metsToAdd,'metFormulas')
0230     metsToAdd.metFormulas=convertCharArray(metsToAdd.metFormulas);
0231     if numel(metsToAdd.metFormulas)~=nMets
0232         EM='metsToAdd.metFormulas must have the same number of elements as metsToAdd.mets';
0233         dispEM(EM);
0234     end
0235     %Add empty field if it doesn't exist
0236     if ~isfield(newModel,'metFormulas')
0237         newModel.metFormulas=largeFiller;
0238     end
0239     newModel.metFormulas=[newModel.metFormulas;metsToAdd.metFormulas(:)];
0240 else
0241     %Add default
0242     if isfield(newModel,'metFormulas')
0243         newModel.metFormulas=[newModel.metFormulas;filler];
0244     end
0245 end
0246 
0247 if isfield(metsToAdd,'metCharges')
0248     if numel(metsToAdd.metCharges)~=nMets
0249         EM='metsToAdd.metCharges must have the same number of elements as metsToAdd.mets';
0250         dispEM(EM);
0251     end
0252     if ~isnumeric(metsToAdd.metCharges)
0253         EM='metsToAdd.metCharges must be of type "double"';
0254         dispEM(EM);
0255     end
0256     if ~isfield(newModel,'metCharges')
0257         newModel.metCharges=NaN(numel(largeFiller),1);
0258     end
0259     newModel.metCharges=[newModel.metCharges;metsToAdd.metCharges(:)];
0260 else
0261     %Add default
0262     if isfield(newModel,'metCharges')
0263         newModel.metCharges=[newModel.metCharges;NaN(numel(filler),1)];
0264     end
0265 end
0266 
0267 if isfield(metsToAdd,'metDeltaG')
0268     if numel(metsToAdd.metDeltaG)~=nMets
0269         EM='metsToAdd.metDeltaG must have the same number of elements as metsToAdd.mets';
0270         dispEM(EM);
0271     end
0272     if ~isnumeric(metsToAdd.metDeltaG)
0273         EM='metsToAdd.metDeltaG must be of type "double"';
0274         dispEM(EM);
0275     end
0276     if ~isfield(newModel,'metDeltaG')
0277         newModel.metDeltaG=NaN(numel(largeFiller),1);
0278     end
0279     newModel.metDeltaG=[newModel.metDeltaG;metsToAdd.metDeltaG(:)];
0280 else
0281     %Add default
0282     if isfield(newModel,'metDeltaG')
0283         newModel.metDeltaG=[newModel.metDeltaG;NaN(numel(filler),1)];
0284     end
0285 end
0286 
0287 
0288 if isfield(metsToAdd,'metNotes')
0289     metsToAdd.metNotes=convertCharArray(metsToAdd.metNotes);
0290     if numel(metsToAdd.metNotes)==1 && numel(metsToAdd.mets)>1
0291         temp=cell(numel(metsToAdd.mets),1);
0292         temp(:)=metsToAdd.metNotes;
0293         metsToAdd.metNotes=temp;
0294     end
0295     if numel(metsToAdd.metNotes)~=nMets
0296         EM='metsToAdd.metNotes must have the same number of elements as metsToAdd.mets';
0297         dispEM(EM);
0298     end
0299     %Add empty field if it doesn't exist
0300     if ~isfield(newModel,'metNotes')
0301         newModel.metNotes=largeFiller;
0302     end
0303     newModel.metNotes=[newModel.metNotes;metsToAdd.metNotes(:)];
0304 else
0305     %Add empty strings if structure is in model
0306     if isfield(newModel,'metNotes')
0307         newModel.metNotes=[newModel.metNotes;filler];
0308     end
0309 end
0310 
0311 %Don't check the type of metMiriams
0312 if isfield(metsToAdd,'metMiriams')
0313     if numel(metsToAdd.metMiriams)==1 && numel(metsToAdd.mets)>1
0314         temp=cell(numel(metsToAdd.mets),1);
0315         temp(:)={metsToAdd.metMiriams};
0316         metsToAdd.metMiriams=temp;
0317     end
0318     if numel(metsToAdd.metMiriams)~=nMets
0319         EM='metsToAdd.metMiriams must have the same number of elements as metsToAdd.mets';
0320         dispEM(EM);
0321     end
0322     %Add empty field if it doesn't exist
0323     if ~isfield(newModel,'metMiriams')
0324         newModel.metMiriams=cell(nOldMets,1);
0325     end
0326     newModel.metMiriams=[newModel.metMiriams;metsToAdd.metMiriams(:)];
0327 else
0328     if isfield(newModel,'metMiriams')
0329         newModel.metMiriams=[newModel.metMiriams;cell(nMets,1)];
0330     end
0331 end
0332 
0333 if isfield(newModel,'metFrom')
0334     newModel.metFrom=[newModel.metFrom;filler];
0335 end
0336 
0337 %Expand the S matrix
0338 newModel.S=[newModel.S;sparse(nMets,size(newModel.S,2))];
0339 
0340 if copyInfo==true
0341     [I, J]=ismember(metsToAdd.metNames,model.metNames);
0342     J=J(I);
0343     %I is the indexes of the new metabolites for which a metabolite with
0344     %the same name existed
0345     I=find(I)+nOldMets;
0346     %Go through each of the added mets and copy annotation if it doesn't
0347     %exist
0348     for i=1:numel(I)
0349         if isfield(newModel,'inchis')
0350             if isempty(newModel.inchis{I(i)})
0351                 newModel.inchis(I(i))=newModel.inchis(J(i));
0352             end
0353         end
0354         if isfield(newModel,'metSmiles')
0355             if isempty(newModel.metSmiles{I(i)})
0356                 newModel.metSmiles(I(i))=newModel.metSmiles(J(i));
0357             end
0358         end        
0359         if isfield(newModel,'metFormulas')
0360             if isempty(newModel.metFormulas{I(i)})
0361                 newModel.metFormulas(I(i))=newModel.metFormulas(J(i));
0362             end
0363         end
0364         if isfield(newModel,'metMiriams')
0365             if isempty(newModel.metMiriams{I(i)})
0366                 newModel.metMiriams(I(i))=newModel.metMiriams(J(i));
0367             end
0368         end
0369         if isfield(newModel,'metCharges')
0370             newModel.metCharges(I(i))=newModel.metCharges(J(i));
0371         end
0372         if isfield(newModel,'metDeltaG')
0373             newModel.metDeltaG(I(i))=newModel.metDeltaG(J(i));
0374         end
0375     end
0376 end
0377 end

Generated by m2html © 2005