1
1
function [modelProp ,ScoresOverall ] = generateMetaboScore(model ,nworkers )
2
-
3
- % Ines Thiele June 2022
2
+ % Analyzes metabolic model properties and generates scores.
3
+ % This function analyzes various aspects of the metabolic model,
4
+ % including basic properties, stoichiometric consistency, matrix conditioning,
5
+ % annotation of metabolites, reactions, genes, SBO terms, and generates
6
+ % overall scores for different aspects.
7
+ %
8
+ % USAGE:
9
+ % [modelProp, ScoresOverall] = generateMetaboScore(model, nworkers)
10
+ %
11
+ % INPUTS:
12
+ % - model: metabolic model structure (COBRA Toolbox format)
13
+ % - nworkers: (optional) number of workers for parallel processing
14
+ %
15
+ % OUTPUT:
16
+ % - modelProp: structure containing various properties of the metabolic model
17
+ % - ScoresOverall: structure containing overall scores for different aspects
18
+ %
19
+ % EXAMPLE:
20
+ % [modelProp, ScoresOverall] = generateMetaboScore(model)
21
+ % [modelProp, ScoresOverall] = generateMetaboScore(model, 4)
22
+ %
23
+ % .. Author: -Ines Thiele June 2022
4
24
5
25
if ~exist(' nworkers' ,' var' )
6
26
nworkers = 4 ;
95
115
modelProp.Details.SinkRxns = [model .rxns(contains(model .rxns ,' Sink_' ));model .rxns(contains(model .rxns ,' sink_' ))];
96
116
% biomass reactions
97
117
modelProp.BiomassRxns = BioR ;
98
- modelProp.Details.BiomassRxns = model .rxns(contains(lower(model .rxns ,' biomass' ) ));% exclude EX_biomass?
118
+ modelProp.Details.BiomassRxns = model .rxns(contains(lower(model .rxns ) ,' biomass' ));% exclude EX_biomass?
99
119
100
120
modelProp.MetabolicRxns = MetR ;
101
121
modelProp.Details.MetabolicRxns = MetRxns ' ;
102
122
modelProp.TransportRxns = TransR ;
103
123
modelProp.Details.TransportRxns = TransRxns ' ;
104
124
105
- % internal reactions without GPR
125
+ % internal reactions without GPR
106
126
RxnsWOGpr = model .rxns(find(cellfun(@isempty ,model .grRules )));
107
127
External = [modelProp .Details .ExchangeRxns ;modelProp .Details .DemandRxns ;modelProp .Details .SinkRxns ;modelProp .Details .BiomassRxns ];
108
128
RxnsWOGpr = setdiff(RxnsWOGpr ,External );
257
277
% remove met from variable metWOAnno (metabolite without
258
278
% annotation)
259
279
metWOAnno = (intersect(metWOAnno ,missingMet )) ;
260
-
280
+
261
281
% get number of metabolites with annotation that conform with
262
282
% database id format
263
283
% test format
264
284
clear confF* missing
265
285
if contains(fields(i ,2 ),' ###' )
266
286
strs = strsplit(fields{i ,2 },' ###' );
267
-
287
+
268
288
confFormat1 = model.(fields{i ,1 })(find(cellfun(@(x )~isempty(x ),regexp(model.(fields{i ,1 }), strs{1 }))));
269
289
confFormat2 = model.(fields{i ,1 })(find(cellfun(@(x )~isempty(x ),regexp(model.(fields{i ,1 }), strs{2 }))));
270
290
confFormat = unique([confFormat1 ;confFormat2 ]);
271
-
291
+
272
292
confFormatM1 = model .mets(find(cellfun(@(x )~isempty(x ),regexp(model.(fields{i ,1 }), strs{1 }))));
273
293
confFormatM2 = model .mets(find(cellfun(@(x )~isempty(x ),regexp(model.(fields{i ,1 }), strs{2 }))));
274
294
confFormatM = unique([confFormatM1 ;confFormatM2 ]);
275
-
295
+
276
296
% remove any potential NaN
277
297
confFormat(ismember(confFormat ,' NaN' ))=[];
278
298
confFormatM(ismember(confFormat ,' NaN' ))=[];
279
-
299
+
280
300
confFormatM = split(confFormatM ,' [' );
281
301
confFormatM = unique(confFormatM(: ,1 ));
282
302
modelProp.(strcat(' AnnoMetConf' , fields{i }))= (length(confFormatM ))*100 /(modelProp .metUnique - length(missingMet )); % how many have it
283
303
p = setdiff(modelProp .Details .metabolites_unique , missingMet );
284
-
304
+
285
305
NonConf = setdiff(p ,confFormatM );
286
306
modelProp .Details.(strcat(' AnnoMetNonConf' , fields{i })) = NonConf ;
287
307
else
290
310
% remove any potential NaN
291
311
confFormatM(ismember(confFormat ,' NaN' ))=[];
292
312
confFormat(ismember(confFormat ,' NaN' ))=[];
293
-
313
+
294
314
confFormatM = split(confFormatM ,' [' );
295
315
confFormatM = unique(confFormatM(: ,1 ));
296
316
modelProp.(strcat(' AnnoMetConf' , fields{i }))= (length(confFormatM ))*100 /(modelProp .metUnique - length(missingMet )); % how many have it
297
317
p = setdiff(modelProp .Details .metabolites_unique , missingMet );
298
-
318
+
299
319
NonConf = setdiff(p ,confFormatM );
300
320
modelProp .Details.(strcat(' AnnoMetNonConf' , fields{i })) = NonConf ;
301
321
end
304
324
modelProp.(strcat(' AnnoMet' ,fields{i })) = 0 ; % how many have it
305
325
modelProp.(strcat(' AnnoMetConf' , fields{i })) = 0 ; % how many have it
306
326
modelProp .Details.(strcat(' AnnoMetNonConf' , fields{i })) = {};
307
-
308
-
327
+
328
+
309
329
end
310
330
end
311
331
% Presence of Metabolite Annotation
345
365
for i = 1 : size(fields )
346
366
if isfield(model ,fields{i ,1 })
347
367
missingRxn = model .rxns(cellfun(' isempty' , model.(fields{i ,1 })));
348
-
368
+
349
369
modelProp .Details.(strcat(' missing' , fields{i })) = missingRxn ;
350
370
modelProp.(strcat(' AnnoRxn' , fields{i }))= (modelProp .n - length(missingRxn ))*100 / modelProp .n ; % how many have it
351
371
% remove rxn from variable rxnWOAnno (reaction without
352
372
% annotation)
353
373
rxnWOAnno = (intersect(rxnWOAnno ,missingRxn )) ;
354
-
374
+
355
375
% get number of reactions with annotation that conform with
356
376
% database id format
357
377
% test format
361
381
confFormat2 = model .rxns(find(cellfun(@(x )~isempty(x ),regexp(model.(fields{i ,1 }), strs{2 }))));
362
382
confFormat3 = model .rxns(find(cellfun(@(x )~isempty(x ),regexp(model.(fields{i ,1 }), strs{3 }))));
363
383
confFormat = [confFormat1 ;confFormat2 ;confFormat3 ];
364
-
384
+
365
385
modelProp.(strcat(' AnnoRxnConf' , fields{i }))= (length(confFormat ))*100 /(modelProp .n - length(missingRxn )); % how many have it
366
-
386
+
367
387
p = setdiff(model .rxns , missingRxn );
368
388
NonConf = setdiff(p ,confFormat );
369
389
modelProp .Details.(strcat(' AnnoRxnNonConf' , fields{i })) = NonConf ;
373
393
p = setdiff(model .rxns , missingRxn );
374
394
NonConf = setdiff(p ,confFormat );
375
395
modelProp .Details.(strcat(' AnnoRxnNonConf' , fields{i })) = NonConf ;
376
-
396
+
377
397
end
378
398
else
379
399
modelProp .Details.(strcat(' missing' ,fields{i })) = model .rxns ;
380
400
modelProp.(strcat(' AnnoRxn' ,fields{i })) = 0 ; % how many have it
381
401
modelProp.(strcat(' AnnoRxnConf' , fields{i })) = 0 ; % how many have it
382
402
modelProp .Details.(strcat(' AnnoRxnNonConf' , fields{i })) = {};
383
-
403
+
384
404
end
385
405
%
386
406
end
425
445
for i = 1 : size(fields )
426
446
if isfield(model ,fields{i ,1 })
427
447
missingGene = model .genes(cellfun(' isempty' , model.(fields{i ,1 })));
428
-
448
+
429
449
modelProp .Details.(strcat(' missing' , fields{i })) = missingGene ;
430
450
modelProp.(strcat(' AnnoGene' , fields{i }))= (length(model .genes ) - length(missingGene ))*100 / length(model .genes ); % how many have it
431
451
% remove rxn from variable geneWOAnno (reaction without
432
452
% annotation)
433
-
453
+
434
454
% get number of reactions with annotation that conform with
435
455
% database id format
436
456
% test format
449
469
confFormat = [confFormat1 ;confFormat2 ;confFormat3 ;confFormat4 ];
450
470
end
451
471
modelProp.(strcat(' AnnoGeneConf' , fields{i }))= (length(confFormat ))*100 /(length(model .genes ) - length(missingGene )); % how many have it
452
-
472
+
453
473
p = setdiff(model .genes , missingGene );
454
474
NonConf = setdiff(p ,confFormat );
455
475
modelProp .Details.(strcat(' AnnoGeneNonConf' , fields{i })) = NonConf ;
456
476
else
457
477
confFormat = model.(fields{i ,1 })(find(cellfun(@(x )~isempty(x ),regexp(model.(fields{i ,1 }), fields(i ,2 )))));
458
478
modelProp.(strcat(' AnnoGeneConf' , fields{i }))= (length(confFormat ))*100 /(length(model .genes ) - length(missingGene )); % how many have it
459
-
479
+
460
480
p = setdiff(model .genes , missingGene );
461
481
NonConf = setdiff(p ,confFormat );
462
482
modelProp .Details.(strcat(' AnnoGeneNonConf' , fields{i })) = NonConf ;
566
586
567
587
modelProp.Scores.Overall = (3 * modelProp .Scores .Consistency + modelProp .Scores .AnnotationMetabolites + modelProp .Scores .AnnotationReactions + ...
568
588
modelProp .Scores .AnnotationGenes + 2 * modelProp .Scores .AnnotationSBO )*100 /(3 * 100 + 100 + 100 + 100 + 2 * 100 );
569
- ScoresOverall = modelProp .Scores .Overall ;
589
+ ScoresOverall = modelProp .Scores .Overall ;
0 commit comments