Skip to content

Commit

Permalink
Merge pull request #2158 from opencobra/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
ithiele authored Jun 29, 2023
2 parents cb64245 + 047a9fa commit 79e5ecc
Show file tree
Hide file tree
Showing 10 changed files with 456 additions and 9 deletions.
2 changes: 1 addition & 1 deletion external/analysis/octave-networks-toolbox
264 changes: 264 additions & 0 deletions src/base/io/json/model2JSON.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
function model2JSON(model,fileName)
% This function writes a json file from matlab structure.
% I validated json format with https://jsonlint.com/.
%
% INPUT
% model model structure
% fileName name of file including extension .json
%
%
% Ines Thiele, May 2023

if isempty(strfind(fileName,'.json'));
fileName = strcat(fileName,'.json');
end

fid = fopen(fileName, 'w');
fprintf(fid, '{\n');
fprintf(fid, '"metabolites":[\n');
cnt = 1;
% write metabolites
for i = 1 : length(model.mets)
fprintf(fid, '{\n');
met = regexprep(model.mets{i},'\[','_');
met = regexprep(met,'\]','');
fprintf(fid,strcat( '"id":"',met,'",\n'));
fprintf(fid,strcat( '"name":"',model.metNames{i},'",\n'));
x = split(model.mets{i},'[');
comp = regexprep(x{2},'\]','');
fprintf(fid,strcat( '"compartment":"',comp,'",\n'));
fprintf(fid,strcat( '"charge":',num2str(model.metCharges(i)),',\n'));
fprintf(fid,strcat( '"formula":"',(model.metFormulas{i}),'",\n'));
fprintf(fid,'"notes":{\n');
fprintf(fid,'"original_vmh_ids":[\n');
fprintf(fid,strcat('"',model.mets{i},'"\n'));
fprintf(fid,']\n');
fprintf(fid,'},\n');
fprintf(fid,'"annotation":{\n');
if isfield(model, 'metBiGGID')
fprintf(fid,'"bigg.metabolite":[\n');
fprintf(fid,strcat('"',model.metBiGGID{i},'"\n'));
fprintf(fid,'],\n');
end
if isfield(model, 'metBioCycID')
fprintf(fid,'"biocyc":[\n');
model.metBioCycID{i} = regexprep(model.metBioCycID{i},'%','');
fprintf(fid,strcat('"',model.metBioCycID{i},'"\n'));
fprintf(fid,'],\n');
end
if isfield(model, 'metChEBIID')
fprintf(fid,'"chebi":[\n');
fprintf(fid,strcat('"',model.metChEBIID{i},'"\n'));
fprintf(fid,'],\n');
end
if isfield(model, 'metHMDBID')
fprintf(fid,'"hmdb":[\n');
fprintf(fid,strcat('"',model.metHMDBID{i},'"\n'));
fprintf(fid,'],\n');
end
if isfield(model, 'metInchiKey')
fprintf(fid,'"inchi_key":[\n');
fprintf(fid,strcat('"',model.metInchiKey{i},'"'));
fprintf(fid,'],');
end
if isfield(model, 'metKEGGID')
fprintf(fid,'"kegg.compound":[\n');
fprintf(fid,strcat('"',model.metKEGGID{i},'"\n'));
fprintf(fid,'],\n');
end
if isfield(model, 'metMetaNetXID')
fprintf(fid,'"metanetx.chemical":[\n');
fprintf(fid,strcat('"',model.metMetaNetXID{i},'"\n'));
fprintf(fid,'],\n');
end
if isfield(model, 'metReactomeID')
fprintf(fid,'"reactome.compound":[\n');
fprintf(fid,strcat('"',model.metReactomeID{i},'"\n'));
fprintf(fid,'],\n');
end
if isfield(model, 'metSabiork')
fprintf(fid,'"sabiork":[\n');
fprintf(fid,strcat('"',model.metSabiork{i},'"\n'));
fprintf(fid,'],\n');

end
if isfield(model, 'metSBOTerms')
fprintf(fid,strcat('"sbo":"',model.metSBOTerms{i},'",\n'));
end
if isfield(model, 'metSEEDID')
fprintf(fid,'"seed.compound":[\n');
fprintf(fid,strcat('"',model.metSEEDID{i},'"'));
end
fprintf(fid,']\n');
fprintf(fid,'}\n'); % close annotation
if i < length(model.mets)
fprintf(fid,'},\n'); % close metabolite
else
fprintf(fid,'}\n'); % close metabolite
end
end
% close list of metabolites
fprintf(fid,'],\n');

% write reactions
fprintf(fid, '"reactions":[\n');
for i = 1 : length(model.rxns)
fprintf(fid, '{\n');
rxn = model.rxns{i};
fprintf(fid,strcat( '"id":"',rxn,'",\n'));
fprintf(fid,strcat( '"name":"',model.rxnNames{i},'",\n'));
fprintf(fid,'"metabolites":{\n');
[metList, stoichiometries] = findMetsFromRxns(model,i);
metList= metList{1};
stoichiometries = stoichiometries{1};
for j = 1 : length(metList)
met = regexprep(metList{j},'\[','_');
met = regexprep(met,'\]','');
if isempty(strfind(num2str(stoichiometries(j,1)),'.'))
fprintf(fid,strcat('"',met,'":',num2str(stoichiometries(j,1)),'.0'));
else
fprintf(fid,strcat('"',met,'":',num2str(stoichiometries(j,1)),''));
end
if j < length(metList)
fprintf(fid, ',\n');
else
fprintf(fid, '\n');
end
end
fprintf(fid, '},\n');
fprintf(fid,strcat('"lower_bound":',num2str(model.lb(i)),',\n'));
fprintf(fid,strcat('"upper_bound":',num2str(model.ub(i)),',\n'));
fprintf(fid,strcat('"gene_reaction_rule":"',model.grRules{i},'",\n'));
try
fprintf(fid,strcat('"subsystem":"',model.subSystems{i},'",\n'));
catch % there seems to be a cell array in some instances
a=model.subSystems{i};
fprintf(fid,strcat('"subsystem":"',a{1},'",\n'));
end
fprintf(fid,strcat('"notes":','{\n'));
fprintf(fid,strcat('"original_vmh_ids":','[\n'));
fprintf(fid,strcat('"',model.rxns{i},'"\n'));
fprintf(fid,']\n');
fprintf(fid,'},\n');
fprintf(fid,'"annotation":{\n');
fprintf(fid,'"metanetx.reaction":[\n');
fprintf(fid,strcat('"',model.rxnMetaNetXID{i},'"\n'));
fprintf(fid,'],\n');
fprintf(fid,strcat('"sbo":"',model.rxnSBOTerms{i},'"\n'));

fprintf(fid,'}'); % close annotation
if i < length(model.rxns)
fprintf(fid,'},\n'); % close reaction
else
fprintf(fid,'}\n'); % close reaction
end
end
% close list of reactions
fprintf(fid,'],\n');

% write genes
% here is a more comprehensive annotation version from Recon3D
%
% {
% "id":"26_AT1",
% "name":"AOC1",
% "notes":{
% "original_bigg_ids":[
% "26.1"
% ]
% },
% "annotation":{
% "ccds":[
% "CCDS43679.1",
% "CCDS64797.1"
% ],
% "ncbigene":[
% "26"
% ],
% "ncbigi":[
% "73486661",
% "1034654825",
% "1034654831",
% "440918691",
% "1034654829",
% "1034654827"
% ],
% "omim":[
% "104610"
% ],
% "refseq_name":[
% "AOC1"
% ],
% "refseq_synonym":[
% "KAO",
% "DAO",
% "DAO1",
% "ABP",
% "ABP1"
% ],
% "sbo":"SBO:0000243"
% }
% },
fprintf(fid, '"genes":[\n');
for i = 1 : length(model.genes)
fprintf(fid, '{\n');
fprintf(fid,strcat( '"id":"',model.genes{i},'",\n'));
fprintf(fid,strcat( '"name":"','",\n'));
fprintf(fid,strcat( '"notes":{','\n'));
fprintf(fid,strcat( '"original_vmh_ids":[','\n'));
fprintf(fid,strcat( '"',model.genes{i},'"\n'));
fprintf(fid,strcat( ']\n'));
fprintf(fid,strcat( '},\n'));
fprintf(fid,strcat( '"annotation":{','\n'));
fprintf(fid,strcat('"sbo":"',model.geneSBOTerms{i},'"\n'));

fprintf(fid,strcat( '}\n')); % close annotation

if i < length(model.genes)
fprintf(fid, '},\n');
else
fprintf(fid, '}\n');
end
end
% close list of genes
fprintf(fid,'],\n');
% model ID
fprintf(fid, strcat('"id":"',model.modelID,'",\n'));
% compartments
[~, uniqueCompartments, ~, ~] = getCompartment(model.mets);
fprintf(fid, strcat('"compartments":{','\n'));
for i = 1 : length(uniqueCompartments)
if strcmp('c',uniqueCompartments{i})
fprintf(fid, '"c":"cytosol"');
elseif strcmp('e',uniqueCompartments{i})
fprintf(fid, '"e":"extracellular space"');
elseif strcmp('g',uniqueCompartments{i})
fprintf(fid, '"g":"golgi apparatus",');
elseif strcmp('i',uniqueCompartments{i})
fprintf(fid, '"i":"inner mitochondrial compartment"');
elseif strcmp('l',uniqueCompartments{i})
fprintf(fid, '"l":"lysosome"');
elseif strcmp('m',uniqueCompartments{i})
fprintf(fid, '"m":"mitochondria"');
elseif strcmp('n',uniqueCompartments{i})
fprintf(fid, '"n":"nucleus"');
elseif strcmp('r',uniqueCompartments{i})
fprintf(fid, '"r":"endoplasmic reticulum"');
elseif strcmp('p',uniqueCompartments{i})
fprintf(fid, '"p":"periplasm');
elseif strcmp('x',uniqueCompartments{i})
fprintf(fid, '"x":"peroxisome/glyoxysome"');
end
if i < length(uniqueCompartments)
fprintf(fid, ',\n');
else
fprintf(fid, '\n');
end
end
fprintf(fid, '},\n'); % close compartments
if isfield(model,'modelAnnotation')
fprintf(fid, strcat('"version":"',model.modelAnnotation{2},'"\n'));
end

fprintf(fid, '}\n'); % close file
fclose(fid);
8 changes: 7 additions & 1 deletion src/base/io/writeCbModel.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
% OPTIONAL INPUTS:
% varargin: Optional parameters in 'Parametername',value
% format. Available parameterNames are:
% * format: File format to be used ('text', 'xls', 'mat'(default) 'expa' or 'sbml')
% * format: File format to be used ('text', 'xls', 'mat'(default), 'expa', 'json' or 'sbml')
% text will only output data from required fields (with GPR rules converted to string representation)
% xls is restricted to the fields defined in the xls io documentation.
% expa will print all reactions with Exchangers being detected by findExcRxns
Expand All @@ -29,6 +29,7 @@
% - Richard Que 3/17/10 - Added ability to specify compartment names and symbols
% - Longfei Mao 26/04/2016 - Added support for the FBCv2 format
% - Thomas Pfau May 2017 - Changed To Parameter/Value pairs and added flexibility
% - Ines Thiele May 2023 - Added option to write json files
%
% EXAMPLES:
%
Expand Down Expand Up @@ -161,6 +162,8 @@
[fileNameFull, filePath] = uiputfile({'*.mat'});
case 'expa'
[fileNameFull, filePath] = uiputfile({'*.expa'});
case 'json'
[fileNameFull, filePath] = uiputfile({'*.json'});
case 'toselect'
[fileNameFull, filePath] = uiputfile({'*.mat', 'Matlab File'; '*.xml' 'SBML Model'; '*.txt' 'Text Export'; '*.xls;*.xlsx' 'Excel Export'; '*.MPS' 'MPS Export'});
otherwise
Expand Down Expand Up @@ -231,6 +234,9 @@
case 'expa'
convertModelToEX(model,fileName,0,model.rxns(findExcRxns(model)));
%% Uknown
case 'json'
model2JSON(model,fileName);
%% Uknown
otherwise
error('Unknown file format');
end
Expand Down
12 changes: 8 additions & 4 deletions src/dataIntegration/XomicsToModel/XomicsToModel.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
%
% * .activeReactions -cell array of reaction identifiers know to be active based on bibliomic data (Default: empty).
% * .inactiveReactions - cell array of reaction identifiers know to be inactive based on bibliomic data (Default: empty).
i
% * .coupledRxns -Table containing information about the coupled reactions. This includes the coupled reaction identifier, the
% list of coupled reactions, the coefficients of those reactions, the constraint, the sense or the directionality of the constraint,
% and the reference (Default: empty).
Expand Down Expand Up @@ -222,7 +221,7 @@
%
% Requires The COBRA Toolbox and a linear optimisation solver (e.g. Gurobi) to be installed
%
% 2022 German Preciat, Agnieszka Wegrzyn, Ronan Fleming
% 2023 German Preciat, Agnieszka Wegrzyn, Xi Luo, Ronan Fleming

model = genericModel;

Expand Down Expand Up @@ -1030,7 +1029,11 @@
if ~any(activeModelGeneBool)
activeEntrezGeneID = [];
else
activeEntrezGeneID = model.genes(activeModelGeneBool);
try
activeEntrezGeneID = model.genes(activeModelGeneBool);
catch
activeEntrezGeneID = model.genes(find(activeModelGeneBool));
end
end

% Active genes from manual curation
Expand Down Expand Up @@ -1963,6 +1966,7 @@
end

if 0 && param.debug && param.findThermoConsistentFluxSubset

% Identify the flux consistent set
paramFluxConsistency.epsilon = param.fluxEpsilon;
paramFluxConsistency.method = param.fluxCCmethod;
Expand Down Expand Up @@ -2214,4 +2218,4 @@
fprintf('%s', 'XomicsToModel run is complete at:')
fprintf('%s\n', datetime)
end
end
end
Loading

0 comments on commit 79e5ecc

Please sign in to comment.