editMiriam Change MIRIAM annotation fields, one annotation type at the same time. Input: model model structure type 'met', 'rxn', 'gene' or 'comp' dependent on which objects the annotations should be assigned to object either a cell array of IDs, a logical vector with the same number of elements as the type (see above) in the model, a vector of indexes, or 'all' miriamName string specifying the namespace of the identifier, for instance 'bigg.metabolite'. Should be a valid prefix from identifiers.org (e.g. https://registry.identifiers.org/registry/bigg.metabolite) miriam string or cell array of strings with annotation identifiers, e.g. '12dgr161' keep one of the following strings, specifying what should be done if an object already has an existing MIRIAM annotations with the same miriamName: 'replace' discard all existing annotations, all will be overwritten, even if the new annotation is an empty field. Should only be used if you do not want to keep any of the old annotation with the same miriamName 'fill' only add annotations to those objects that did not yet have an annotation with that miriamName. Otherwise, the existing annotation is kept, even if it is different from the suggested new annotation 'add' keep all existing annotations, and add any new annotations, after removing duplicates Ouput: model model structure with updated MIRIAM annotation field Usage: model=editMiriam(model,type,object,miriamName,miriams,keep)
0001 function model=editMiriam(model,type,object,miriamName,miriams,keep) 0002 % editMiriam 0003 % Change MIRIAM annotation fields, one annotation type at the same time. 0004 % 0005 % Input: 0006 % model model structure 0007 % type 'met', 'rxn', 'gene' or 'comp' dependent on which 0008 % objects the annotations should be assigned to 0009 % object either a cell array of IDs, a logical vector with the 0010 % same number of elements as the type (see above) in the 0011 % model, a vector of indexes, or 'all' 0012 % miriamName string specifying the namespace of the identifier, for 0013 % instance 'bigg.metabolite'. Should be a valid prefix 0014 % from identifiers.org (e.g. 0015 % https://registry.identifiers.org/registry/bigg.metabolite) 0016 % miriam string or cell array of strings with annotation 0017 % identifiers, e.g. '12dgr161' 0018 % keep one of the following strings, specifying what should be 0019 % done if an object already has an existing MIRIAM 0020 % annotations with the same miriamName: 0021 % 'replace' discard all existing annotations, all will 0022 % be overwritten, even if the new annotation 0023 % is an empty field. Should only be used if 0024 % you do not want to keep any of the old 0025 % annotation with the same miriamName 0026 % 'fill' only add annotations to those objects that 0027 % did not yet have an annotation with that 0028 % miriamName. Otherwise, the existing 0029 % annotation is kept, even if it is different 0030 % from the suggested new annotation 0031 % 'add' keep all existing annotations, and add any 0032 % new annotations, after removing duplicates 0033 % 0034 % Ouput: 0035 % model model structure with updated MIRIAM annotation field 0036 % 0037 % Usage: model=editMiriam(model,type,object,miriamName,miriams,keep) 0038 miriamName=char(miriamName); 0039 miriams=convertCharArray(miriams); 0040 0041 %Check 'keep' input 0042 keep=char(keep); 0043 if ~any(strcmp(keep,{'replace','fill','add'})) 0044 error('Invalid ''keep'', should be ''replace'',''fill'',''add''.') 0045 end 0046 %Check 'type' input 0047 type=char(type); 0048 if ~any(strcmp(type,{'met','gene','rxn','comp'})) 0049 error('Invalid ''type'', should be ''met'', ''gene'', ''rxn'' or ''comp''.') 0050 end 0051 %Check 'object' input 0052 if islogical(object) 0053 idxInModel=find(object); 0054 elseif isnumeric(object) 0055 idxInModel=object; 0056 else 0057 object=convertCharArray(object); 0058 if numel(object)==1 && strcmp(object{1},'all') 0059 idxInModel=1:numel(model.([type,'s'])); 0060 else 0061 idxInModel=getIndexes(model,object,[type,'s']); 0062 if ~all(idxInModel) 0063 dispEM('The following objects cannot be found in the model: ',true,object(~idxInModel)) 0064 end 0065 end 0066 end 0067 %Check 'miriams' input 0068 if numel(miriams)==1 && numel(idxInModel)~=1 0069 miriams=repmat(miriams,numel(idxInModel),1); 0070 elseif numel(miriams)~=numel(idxInModel) 0071 error('The number of annotations does not match the number of objects.') 0072 end 0073 0074 miriamFieldName=[type,'Miriams']; 0075 0076 if isfield(model,miriamFieldName) 0077 [extractedMiriams,extractedMiriamNames]=extractMiriam(model.(miriamFieldName)(idxInModel),'all'); 0078 else 0079 extractedMiriams=cell(numel(idxInModel),1); 0080 extractedMiriamNames={miriamName}; 0081 end 0082 0083 [~, midx]=ismember(miriamName,extractedMiriamNames); 0084 if midx==0 0085 midx=numel(extractedMiriamNames)+1; 0086 extractedMiriamNames(end+1)={miriamName}; 0087 extractedMiriams(:,end+1)=miriams; 0088 elseif strcmp(keep,'replace') 0089 extractedMiriams(:,midx)=miriams; 0090 else 0091 noMiriam=cellfun(@isempty,extractedMiriams(:,midx)); 0092 extractedMiriams(noMiriam,midx)=miriams(noMiriam); 0093 if strcmp(keep,'add') % Skipped when only filling empty entries 0094 existingMiriams=[split(extractedMiriams(~noMiriam,midx),'; '), miriams(~noMiriam)]; 0095 uniqueMiriams=cell(size(existingMiriams,1),1); 0096 for i=1:size(existingMiriams,1) 0097 uniqueMiriams{i,1}=strjoin(unique(existingMiriams(i,:)), {'; '}); 0098 end 0099 extractedMiriams(~noMiriam,midx)=uniqueMiriams; 0100 end 0101 end 0102 0103 % Make Miriam field again 0104 for i=1:numel(idxInModel) 0105 miriam.name=cell(1,1); 0106 miriam.value=cell(1,1); 0107 for j=1:numel(extractedMiriamNames) 0108 if ~isempty(extractedMiriams{i,j}) 0109 values=strsplit(extractedMiriams{i,j},'; '); 0110 miriam.name(end+1:end+numel(values),1)=extractedMiriamNames(j); 0111 miriam.value(end+1:end+numel(values),1)=values; 0112 end 0113 end 0114 miriam.name(1)=[]; 0115 miriam.value(1)=[]; 0116 model.(miriamFieldName){idxInModel(i),1}=miriam; 0117 end 0118 end