diff --git a/examples/Community Modeling/smetana/commscores_report.html b/examples/Community Modeling/smetana/commscores_report.html index 06d8f7cc..cfca21d0 100644 --- a/examples/Community Modeling/smetana/commscores_report.html +++ b/examples/Community Modeling/smetana/commscores_report.html @@ -20,7 +20,6 @@ } } - @@ -43,12 +42,13 @@

CommScores Results

\ No newline at end of file diff --git a/examples/Community Modeling/smetana/debugging_CommScores_app.ipynb b/examples/Community Modeling/smetana/debugging_CommScores_app.ipynb index 7c222996..2fd63991 100644 --- a/examples/Community Modeling/smetana/debugging_CommScores_app.ipynb +++ b/examples/Community Modeling/smetana/debugging_CommScores_app.ipynb @@ -33,7 +33,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "1e337787-35ad-4080-9c53-122b8d87f07d", "metadata": {}, "outputs": [ @@ -41,13 +41,100 @@ "name": "stdout", "output_type": "stream", "text": [ - "The minimal flux media consists of 39 compounds and a 1.9434348647780746 total influx, with a growth value of 0.10000000000010684\n", - "The minimal flux media consists of 39 compounds and a 1.8979898582835117 total influx, with a growth value of 0.10000000000040826\n", + "The minimal flux media consists of 39 compounds and a 1.9434348647775859 total influx, with a growth value of 0.10000000000007983\n", + "The minimal flux media consists of 39 compounds and a 1.8979898582455417 total influx, with a growth value of 0.09999999999891523\n", "The minimal media of all members:\n", - "{'Pseudomonas_sp._GM17_2511231006.fna.RAST.fbamodel': {'media': {'EX_cpd00156_e0': 0.035223318909420306, 'EX_cpd00793_e0': 0.000280615915959131, 'EX_cpd00654_e0': 0.005215640721434261, 'EX_cpd00179_e0': 0.06274188137490219, 'EX_cpd10515_e0': 0.0008418477478773932, 'EX_cpd00007_e0': 0.0008418477478773933, 'EX_cpd00311_e0': 0.015193123296078484, 'EX_cpd00058_e0': 0.00028061591595913103, 'EX_cpd00254_e0': 0.00028061591595913103, 'EX_cpd00069_e0': 0.012067660460661201, 'EX_cpd00063_e0': 0.0002806159159591311, 'EX_cpd00034_e0': 0.00028061591595913103, 'EX_cpd00220_e0': 0.0008418477478773932, 'EX_cpd01017_e0': 0.008456496968442235, 'EX_cpd00644_e0': 0.0005612318319182638, 'EX_cpd00215_e0': 0.00028061591595913103, 'EX_cpd00322_e0': 0.0241798510337235, 'EX_cpd00104_e0': 0.00028061591595913103, 'EX_cpd00205_e0': 0.00028061591595913103, 'EX_cpd00107_e0': 0.03753888475401271, 'EX_cpd00149_e0': 0.00028061591595913103, 'EX_cpd00065_e0': 0.00472019191450218, 'EX_cpd00048_e0': 0.00028061591595913103, 'EX_cpd00119_e0': 0.007926360007371592, 'EX_cpd00099_e0': 0.00028061591595913103, 'EX_cpd00355_e0': 1.18422356313892, 'EX_cpd01080_e0': 0.024916275954454087, 'EX_cpd00017_e0': 0.013060758175035837, 'EX_cpd00136_e0': 0.00028061591595913103, 'EX_cpd00066_e0': 0.015451949003134503, 'EX_cpd00438_e0': 0.0011917803122624656, 'EX_cpd00209_e0': 0.44760816358423205, 'EX_cpd00028_e0': 0.00028061591595913103, 'EX_cpd00264_e0': 0.00028061591595913103, 'EX_cpd00030_e0': 0.0002806159159591311, 'EX_cpd03847_e0': 0.002501059771089441, 'EX_cpd00307_e0': 0.00841036156544863, 'EX_cpd00393_e0': 0.0008418477478773854, 'EX_cpd00051_e0': 0.0246696822701341}}, 'Sphingobium_sp._AP49_2512564014.fna.RAST.fbamodel': {'media': {'EX_cpd00156_e0': 0.03522331890916251, 'EX_cpd00793_e0': 0.00028061591595913103, 'EX_cpd00654_e0': 0.0011789605965904404, 'EX_cpd10515_e0': 0.0008418477478773931, 'EX_cpd00009_e0': 0.08097478546577376, 'EX_cpd00007_e0': 1.1741528321292758, 'EX_cpd00058_e0': 0.000280615915959131, 'EX_cpd00254_e0': 0.00028061591595913103, 'EX_cpd00069_e0': 0.012067660460661201, 'EX_cpd00063_e0': 0.0002806159159591311, 'EX_cpd00118_e0': 0.0002806159159591311, 'EX_cpd00034_e0': 0.0002806159159591311, 'EX_cpd00220_e0': 0.0008418477478773931, 'EX_cpd01017_e0': 0.008456496968391312, 'EX_cpd00039_e0': 0.028543802049017897, 'EX_cpd00644_e0': 0.0005612318318673393, 'EX_cpd00215_e0': 0.00028061591595913103, 'EX_cpd00277_e0': 0.0020247366767531506, 'EX_cpd00322_e0': 0.024179851033723502, 'EX_cpd00104_e0': 0.000280615915959131, 'EX_cpd00205_e0': 0.000280615915959131, 'EX_cpd00107_e0': 0.037538884754166196, 'EX_cpd00149_e0': 0.00028061591595913103, 'EX_cpd00065_e0': 0.004720191914502182, 'EX_cpd00048_e0': 0.000280615915959131, 'EX_cpd00119_e0': 0.16897710575026803, 'EX_cpd00099_e0': 0.00028061591595913103, 'EX_cpd01080_e0': 0.024916275954454083, 'EX_cpd00017_e0': 0.0019643114117139167, 'EX_cpd00136_e0': 0.00028061591595913103, 'EX_cpd00066_e0': 0.015451949003134503, 'EX_cpd00794_e0': 0.23177487667053182, 'EX_cpd00060_e0': 0.011096446763321907, 'EX_cpd00028_e0': 0.000280615915959131, 'EX_cpd00264_e0': 0.0002806159159591311, 'EX_cpd00030_e0': 0.0002806159159591311, 'EX_cpd03847_e0': 0.0025010597710894396, 'EX_cpd00393_e0': 0.0008418477478774358, 'EX_cpd00051_e0': 0.0246696822701341}}}\n", + "{'Pseudomonas_sp._GM17_2511231006.fna.RAST.fbamodel': {'media': {'EX_cpd00220_e0': 0.0008418477478773932, 'EX_cpd00793_e0': 0.000280615915959131, 'EX_cpd00264_e0': 0.00028061591595913103, 'EX_cpd00393_e0': 0.0008418477478773958, 'EX_cpd00119_e0': 0.007926360007371592, 'EX_cpd00205_e0': 0.00028061591595913103, 'EX_cpd00030_e0': 0.0002806159159591311, 'EX_cpd03847_e0': 0.002501059771089441, 'EX_cpd00048_e0': 0.00028061591595913103, 'EX_cpd00034_e0': 0.00028061591595913103, 'EX_cpd00051_e0': 0.0246696822701341, 'EX_cpd10515_e0': 0.0008418477478773932, 'EX_cpd00209_e0': 0.44760816358394934, 'EX_cpd00058_e0': 0.00028061591595913103, 'EX_cpd00179_e0': 0.06274188137470496, 'EX_cpd00066_e0': 0.015451949003134503, 'EX_cpd00254_e0': 0.00028061591595913103, 'EX_cpd00028_e0': 0.00028061591595913103, 'EX_cpd00063_e0': 0.0002806159159591311, 'EX_cpd00644_e0': 0.0005612318319182638, 'EX_cpd00438_e0': 0.0011917803122624656, 'EX_cpd00065_e0': 0.00472019191450218, 'EX_cpd01017_e0': 0.008456496968442235, 'EX_cpd00215_e0': 0.00028061591595913103, 'EX_cpd00654_e0': 0.005215640721434261, 'EX_cpd00136_e0': 0.00028061591595913076, 'EX_cpd00322_e0': 0.0241798510337235, 'EX_cpd00007_e0': 0.0008418477478773925, 'EX_cpd00156_e0': 0.035223318909502234, 'EX_cpd00069_e0': 0.012067660460661201, 'EX_cpd00355_e0': 1.1842235631389384, 'EX_cpd00104_e0': 0.00028061591595913103, 'EX_cpd00149_e0': 0.00028061591595913103, 'EX_cpd00307_e0': 0.008410361565448637, 'EX_cpd00311_e0': 0.015193123295969044, 'EX_cpd00099_e0': 0.00028061591595913103, 'EX_cpd00107_e0': 0.03753888475401271, 'EX_cpd01080_e0': 0.024916275954454087, 'EX_cpd00017_e0': 0.013060758175035835}}, 'Sphingobium_sp._AP49_2512564014.fna.RAST.fbamodel': {'media': {'EX_cpd00220_e0': 0.0008418477478773931, 'EX_cpd00793_e0': 0.00028061591595913103, 'EX_cpd00264_e0': 0.0002806159159591311, 'EX_cpd00393_e0': 0.0008418477479800973, 'EX_cpd00060_e0': 0.011096446763321914, 'EX_cpd00119_e0': 0.16897710574146574, 'EX_cpd00205_e0': 0.000280615915959131, 'EX_cpd00030_e0': 0.0002806159159591311, 'EX_cpd00118_e0': 0.0002806159159591311, 'EX_cpd03847_e0': 0.0025010597710894396, 'EX_cpd00048_e0': 0.000280615915959131, 'EX_cpd00034_e0': 0.0002806159159591311, 'EX_cpd00051_e0': 0.0246696822701341, 'EX_cpd10515_e0': 0.0008418477478773931, 'EX_cpd00058_e0': 0.000280615915959131, 'EX_cpd00066_e0': 0.015451949003134503, 'EX_cpd00254_e0': 0.00028061591595913103, 'EX_cpd00028_e0': 0.000280615915959131, 'EX_cpd00063_e0': 0.0002806159159591311, 'EX_cpd00644_e0': 0.0005612318320293196, 'EX_cpd00065_e0': 0.004720191914502182, 'EX_cpd00794_e0': 0.23177487666228458, 'EX_cpd01017_e0': 0.008456496968553296, 'EX_cpd00215_e0': 0.00028061591595913103, 'EX_cpd00654_e0': 0.0011789605965904404, 'EX_cpd00009_e0': 0.08097478545687763, 'EX_cpd00136_e0': 0.00028061591595913114, 'EX_cpd00039_e0': 0.0285438020490179, 'EX_cpd00322_e0': 0.024179851033723502, 'EX_cpd00007_e0': 1.1741528321169399, 'EX_cpd00156_e0': 0.0352233189090214, 'EX_cpd00277_e0': 0.0020247366767794624, 'EX_cpd00069_e0': 0.012067660460661201, 'EX_cpd00104_e0': 0.000280615915959131, 'EX_cpd00149_e0': 0.00028061591595913103, 'EX_cpd00099_e0': 0.00028061591595913103, 'EX_cpd00107_e0': 0.037538884754166196, 'EX_cpd01080_e0': 0.024916275954454083, 'EX_cpd00017_e0': 0.0019643114117139167}}}\n", "\n", - "Examining the 1 model pairs\n" + "Examining the 1 model pairs\n", + "cpd11416_c0 bio1: 0.5 cpd11416_c1 + 0.5 cpd11416_c2 --> cpd11416_c0;\tcpd11416_c0 SK_cpd11416_c0: cpd11416_c0 <=> ;\tMainProcess~~0\t['Pseudomonas_sp._GM17_2511231006.fna.RAST.fbamodel', 'Sphingobium_sp._AP49_2512564014.fna.RAST.fbamodel']\n" ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
model1model2mediaMRO_model1MRO_model2CIPMIP_model1MIP_model2PCBSS_model1BSS_model2BITGYDFC
0Pseudomonas_sp._GM17_2511231006.fna.RAST.fbamodelSphingobium_sp._AP49_2512564014.fna.RAST.fbamodelR2A_edition_0030.84615 (33/39)0.84615 (33/39)213 (1)11 (3)0.607970.6410260.692308mutualism0.162830.30420
\n", + "
" + ], + "text/plain": [ + " model1 \\\n", + "0 Pseudomonas_sp._GM17_2511231006.fna.RAST.fbamodel \n", + "\n", + " model2 media \\\n", + "0 Sphingobium_sp._AP49_2512564014.fna.RAST.fbamodel R2A_edition_003 \n", + "\n", + " MRO_model1 MRO_model2 CIP MIP_model1 MIP_model2 PC \\\n", + "0 0.84615 (33/39) 0.84615 (33/39) 21 3 (1) 11 (3) 0.60797 \n", + "\n", + " BSS_model1 BSS_model2 BIT GYD FC \n", + "0 0.641026 0.692308 mutualism 0.16283 0.30420 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'\\n\\n \\n \\n \\n CommScores Results\\n \\n \\n \\n \\n \\n \\n \\n\\n \\n \\n \\n\\n \\n \\n \\n

CommScores Results

\\n \\n
\\n
\\n

The biomass yields are expressed in [gm/hr*(gm CDW)]

\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n
model1model2mediaMRO_model1MRO_model2CIPMIP_model1MIP_model2PCBSS_model1BSS_model2BITGYDFC
0Pseudomonas_sp._GM17_2511231006.fna.RAST.fbamodelSphingobium_sp._AP49_2512564014.fna.RAST.fbamodelR2A_edition_0030.84615 (33/39)0.84615 (33/39)213 (1)11 (3)0.607970.6410260.692308mutualism0.162830.30420
\\n
\\n
\\n \\n\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n
 MRO_model1MRO_model2CIPMIP_model1MIP_model2PCBSS_model1BSS_model2GYDFC
model1 ++ model2 ___ Media          
Pseudomonas_sp._GM17_2511231006.fna.RAST.fbamodel ++ Sphingobium_sp._AP49_2512564014.fna.RAST.fbamodel in R2A_edition_0030.8461500.84615021.0000003.00000011.0000000.6079700.6410260.6923080.1628300.304200
\\n\\n
\\n
\\n
\\n

Novel scores


\\n\\n

Functional Complementarity (FC)

\\n

\\n The FC score is calculated as the Jiccard Index of ontologies $O$ from either RAST or another annotation software available on KBase [2]\\n

\\n \\\\[ FC= \\\\left( \\\\frac{O_1 \\\\cap O_2}{O_1 \\\\cup O_2} \\\\right)~~. \\\\]\\n
\\n This score captures the potential for niche overlap and therefore negative interactions. The broad assessment of the entire genome further captures secondary metabolic interactions as well as the primary metabolism that is embodied in genome-scale metabolic models.\\n

\\n\\n

Growth Yield Difference (GYD)

\\n

\\n The GYD score evaluates the disparity in growth rate between the isolated members\\n

\\n \\\\[ GYD = \\\\frac{abs(G_{1}-G_{2})}{min(G_{1}, G_{2})}~~, \\\\]\\n
\\n by normalizing the difference in the member\\'s growth rates by the growth rate of the slower growing member. A relatively large disparity in the isolate growth rates may foreshadow a negative interaction when the members are combined, where one member rapidly begins dominating the environment and media consumption which leaves the other member potentially starved and possibly launching antibiotic warfare in desparation to survive.\\n

\\n\\n

Costless Interaction Potential (CIP)

\\n

\\n The CIP score quantifies the union of costless excreta CE (compounds that are excreted at maximal growth and therefore have no fitness cost associated with their excretion) in the isolated members\\n

\\n \\\\[ CIP = len(CE_1 \\\\cup CE_2)~~, \\\\]\\n
\\n which may contextualize syntrophic exchanges in their likelihood for exchange based on the fitness expense of their excretion. Our curation of the MIP score can be further contextualized with costless excreta via the intersection of exchanged compounds in the MIP score and the CIP for the same member pair. \\n

\\n\\n

Biological Interaction Potential (BIT)

\\n

\\n The BIT score categorizes the member interaction into one of the classical descriptions -- competitive, amensalism, neutral, parasitism, commensalism, and mutualism -- based on relative growth of the members as isolates G1 versus in the community environment G1,comm\\n

\\n \\\\[ BIT_1 = G_{1,comm}-G_1 \\\\]\\n
\\n
\\n \\\\[ BIT_2 = G_{2,comm}-G_2 \\\\]\\n
\\n which provides a tangible biological description of the member interaction based on growth through the primary metabolism.\\n

\\n\\n

Curated scores


\\n\\n

MRO

\\n

\\n The Metabolic Resource Overlap (MRO) score is in the SMETANA suite and was published in several earlier studies as well, albeit with slight algorithmic variations. The MRO quantifies the fraction of a member\\'s nutritional requirements, in a given media or the complete media by default, that overlap with the other member\\'s nutritional requirements \\n

\\\\[ MRO= \\\\frac{|M_1 \\\\cap M_2|}{|M_1|} \\\\]
\\n and is importantly directional (by replacing the denominator member), which can capture directional dependencies of interactions (e.g. lawn versus spot). The minimal media $M$ of each member is determined by minimizing the total exchange flux.\\n

\\n\\n

MIP

\\n

\\n The Metabolic Interaction Potential (MIP) score is also in the SMETANA suite and earlier studies. This score quantifies syntrophic exchanges between the members. Our curation computes the MIP as the difference in exchanged compounds versus transported compounds in the compartmentalized community model\\n

\\\\[ MIP=M_{transports}-M_{exchanges}~~, \\\\]
\\n where compounds that the members are transporting but the community is not exchanging with the media must be sourced from syntrophy. The MIP compounds that are costlessly excreted can also be quantified as a subscore of the MIP, and may better represent the compounds that are favorably exchanged in the community.\\n

\\n\\n

PC

\\n

\\n The Potential Cooperation (PC) score quantifies the net effect of co-growth relative to isolate growth, and in our curation is determined as the ratio of community growth to the sum of isolated member growths\\n

\\\\[ PC = \\\\frac{G_{comm}}{G_1+G_2}~~, \\\\]
\\n and is therefore essentially a continuous quantitative representation of the discrete qualitative BIT score.\\n

\\n\\n

BSS

\\n

\\n The Biosynthetic Support Score (BSS) score quantifies the capacity of a member to parasitize another member by topologically evaluating the proportion of a member\\'s nutritional requirements that are in the other member\\'s cytoplasmic metabolites\\n

\\\\[ BSS = \\\\frac{M_i \\\\cap R_j}{M_i}~~. \\\\]
\\n This score therefore quantifies the capacity or incentive for negative interaction.\\n

\\n
\\n \\n
\\n \\n'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -66,60 +153,9 @@ { "cell_type": "code", "execution_count": null, - "id": "2dde6486-b4f4-4483-a244-62c9fcec1e19", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 2, "id": "b9bb7da2-cc19-439a-b692-27ea6e1ccebf", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "./\n", - "The minimal flux media consists of 39 compounds and a 1.9434348647769515 total influx, with a growth value of 0.10000000000004163\n", - "The minimal flux media consists of 33 compounds and a 1.6635843914761332 total influx, with a growth value of 0.10000000000010392\n", - "The minimal flux media consists of 39 compounds and a 1.8979898582822738 total influx, with a growth value of 0.10000000000035089\n", - "The minimal media of all members:\n", - "{'Pseudomonas_sp._GM17_2511231006.fna.RAST.fbamodel': {'media': {'EX_cpd00220_e0': 0.0008418477478773932, 'EX_cpd00438_e0': 0.0011917803122624656, 'EX_cpd00058_e0': 0.00028061591595913103, 'EX_cpd00307_e0': 0.008410361565448629, 'EX_cpd00007_e0': 0.0008418477478773933, 'EX_cpd00149_e0': 0.00028061591595913103, 'EX_cpd00136_e0': 0.00028061591595913103, 'EX_cpd00065_e0': 0.00472019191450218, 'EX_cpd01017_e0': 0.008456496968442235, 'EX_cpd00051_e0': 0.0246696822701341, 'EX_cpd00205_e0': 0.00028061591595913103, 'EX_cpd00179_e0': 0.06274188137467966, 'EX_cpd00119_e0': 0.007926360007371592, 'EX_cpd00654_e0': 0.005215640721434261, 'EX_cpd00311_e0': 0.015193123295876151, 'EX_cpd00048_e0': 0.00028061591595913103, 'EX_cpd03847_e0': 0.002501059771089441, 'EX_cpd00066_e0': 0.015451949003134503, 'EX_cpd00063_e0': 0.0002806159159591311, 'EX_cpd00099_e0': 0.00028061591595913103, 'EX_cpd01080_e0': 0.024916275954454087, 'EX_cpd00034_e0': 0.00028061591595913103, 'EX_cpd00215_e0': 0.00028061591595913103, 'EX_cpd00793_e0': 0.000280615915959131, 'EX_cpd00156_e0': 0.035223318909420306, 'EX_cpd00644_e0': 0.0005612318319182638, 'EX_cpd00107_e0': 0.03753888475401271, 'EX_cpd10515_e0': 0.0008418477478773932, 'EX_cpd00355_e0': 1.1842235631383102, 'EX_cpd00322_e0': 0.0241798510337235, 'EX_cpd00264_e0': 0.00028061591595913103, 'EX_cpd00104_e0': 0.00028061591595913103, 'EX_cpd00209_e0': 0.4476081635841435, 'EX_cpd00017_e0': 0.013060758175035835, 'EX_cpd00069_e0': 0.012067660460661201, 'EX_cpd00028_e0': 0.00028061591595913103, 'EX_cpd00030_e0': 0.0002806159159591311, 'EX_cpd00254_e0': 0.00028061591595913103, 'EX_cpd00393_e0': 0.0008418477478773832}}, 'Variovorax_sp._CF313_2513020051.fna.RAST.fbamodel': {'media': {'EX_cpd00220_e0': 0.0008418477478773236, 'EX_cpd00794_e0': 0.8176244301386079, 'EX_cpd00058_e0': 0.0002806159159591311, 'EX_cpd00307_e0': 0.020977746058791463, 'EX_cpd00007_e0': 0.0007015397898978277, 'EX_cpd00149_e0': 0.0002806159159591311, 'EX_cpd00042_e0': 0.0084564969684422, 'EX_cpd00136_e0': 0.00028061591595913114, 'EX_cpd00065_e0': 0.004720191914502181, 'EX_cpd00051_e0': 0.02466968227013488, 'EX_cpd00205_e0': 0.0002806159159591311, 'EX_cpd00119_e0': 0.007926360007383936, 'EX_cpd00048_e0': 0.0002806159159591311, 'EX_cpd00066_e0': 0.015451949003135547, 'EX_cpd00063_e0': 0.00028061591595913103, 'EX_cpd00099_e0': 0.0002806159159591311, 'EX_cpd00034_e0': 0.00028061591595913103, 'EX_cpd00215_e0': 0.00028061591595913103, 'EX_cpd00793_e0': 0.00028061591595913103, 'EX_cpd00156_e0': 0.0352233189091625, 'EX_cpd00644_e0': 0.0005612318319182279, 'EX_cpd00107_e0': 0.03753888475401271, 'EX_cpd10515_e0': 0.0008418477478773931, 'EX_cpd00355_e0': 0.08097454709426695, 'EX_cpd00322_e0': 0.02417985103372351, 'EX_cpd00104_e0': 0.0002806159159591311, 'EX_cpd00209_e0': 0.5366108058202714, 'EX_cpd00017_e0': 0.029445529354160355, 'EX_cpd00069_e0': 0.012067660460661203, 'EX_cpd00028_e0': 0.0002806159159591311, 'EX_cpd00030_e0': 0.00028061591595913103, 'EX_cpd00254_e0': 0.00028061591595913114, 'EX_cpd00393_e0': 0.0008418477478773866}}, 'Sphingobium_sp._AP49_2512564014.fna.RAST.fbamodel': {'media': {'EX_cpd00220_e0': 0.0008418477478773931, 'EX_cpd00794_e0': 0.23177487666935928, 'EX_cpd00058_e0': 0.000280615915959131, 'EX_cpd00007_e0': 1.1741528321289854, 'EX_cpd00149_e0': 0.00028061591595913103, 'EX_cpd00136_e0': 0.00028061591595913114, 'EX_cpd00065_e0': 0.004720191914502182, 'EX_cpd01017_e0': 0.00845649696851446, 'EX_cpd00051_e0': 0.0246696822701341, 'EX_cpd00205_e0': 0.000280615915959131, 'EX_cpd00118_e0': 0.0002806159159591311, 'EX_cpd00119_e0': 0.1689771057497348, 'EX_cpd00060_e0': 0.011096446763321914, 'EX_cpd00654_e0': 0.0011789605965904404, 'EX_cpd00048_e0': 0.000280615915959131, 'EX_cpd03847_e0': 0.0025010597710894396, 'EX_cpd00009_e0': 0.08097478546647749, 'EX_cpd00066_e0': 0.015451949003134503, 'EX_cpd00277_e0': 0.0020247366767531506, 'EX_cpd00063_e0': 0.0002806159159591311, 'EX_cpd00099_e0': 0.00028061591595913103, 'EX_cpd01080_e0': 0.024916275954454083, 'EX_cpd00034_e0': 0.0002806159159591311, 'EX_cpd00215_e0': 0.00028061591595913103, 'EX_cpd00793_e0': 0.00028061591595913103, 'EX_cpd00156_e0': 0.03522331890916251, 'EX_cpd00644_e0': 0.0005612318319904868, 'EX_cpd00107_e0': 0.037538884754012715, 'EX_cpd10515_e0': 0.0008418477478773931, 'EX_cpd00039_e0': 0.0285438020490179, 'EX_cpd00322_e0': 0.02417985103368549, 'EX_cpd00264_e0': 0.0002806159159591311, 'EX_cpd00104_e0': 0.000280615915959131, 'EX_cpd00017_e0': 0.001964311411713917, 'EX_cpd00069_e0': 0.012067660460661201, 'EX_cpd00028_e0': 0.000280615915959131, 'EX_cpd00030_e0': 0.0002806159159591311, 'EX_cpd00254_e0': 0.00028061591595913103, 'EX_cpd00393_e0': 0.0008418477478773915}}}\n", - "\n", - "Examining the 3 model pairs\n", - "cpd11416_c0 bio1: 0.5 cpd11416_c1 + 0.5 cpd11416_c2 --> cpd11416_c0;\tcpd11416_c0 SK_cpd11416_c0: cpd11416_c0 <=> ;\tMainProcess~~0\t['Pseudomonas_sp._GM17_2511231006.fna.RAST.fbamodel', 'Variovorax_sp._CF313_2513020051.fna.RAST.fbamodel']\n", - "{'cpd00215', 'cpd00209', 'cpd00654', 'cpd00149', 'cpd00307', 'cpd00030', 'cpd00007', 'cpd03847', 'cpd01017', 'cpd00644', 'cpd10515', 'cpd00311', 'cpd01080', 'cpd00793', 'cpd00156', 'cpd00205', 'cpd00322', 'cpd00069', 'cpd00063', 'cpd00107', 'cpd00220', 'cpd00104', 'cpd00099', 'cpd00065', 'cpd00066', 'cpd00264', 'cpd00017', 'cpd00048', 'cpd00355', 'cpd00438', 'cpd00034', 'cpd00028', 'cpd00393', 'cpd00254', 'cpd00179', 'cpd00119', 'cpd00051', 'cpd00136', 'cpd00058'}\n", - "{'cpd03736', 'cpd15523', 'cpd00900', 'cpd00427', 'cpd11524', 'cpd19019', 'cpd00036', 'cpd15533', 'cpd00176', 'cpd02961', 'cpd03521', 'cpd11553', 'cpd00722', 'cpd02465', 'cpd00144', 'cpd00868', 'cpd08289', 'cpd00638', 'cpd03704', 'cpd00200', 'cpd00012', 'cpd07924', 'cpd15417', 'cpd03495', 'cpd00876', 'cpd15531', 'cpd15677', 'cpd00110', 'cpd00298', 'cpd15479', 'cpd15552', 'cpd03211', 'cpd00249', 'cpd02069', 'cpd00521', 'cpd36025', 'cpd03034', 'cpd00022', 'cpd00017', 'cpd00809', 'cpd00525', 'cpd00359', 'cpd00516', 'cpd00873', 'cpd15724', 'cpd15358', 'cpd15421', 'cpd03916', 'cpd12227', 'cpd11490', 'cpd02375', 'cpd00129', 'cpd00759', 'cpd01695', 'cpd00001', 'cpd02068', 'cpd01741', 'cpd01150', 'cpd15544', 'cpd15488', 'cpd02016', 'cpd01399', 'cpd15534', 'cpd11310', 'cpd00101', 'cpd03524', 'cpd00007', 'cpd15727', 'cpd00501', 'cpd11498', 'cpd15542', 'cpd11313', 'cpd00515', 'cpd00508', 'cpd00186', 'cpd00908', 'cpd00061', 'cpd02611', 'cpd00523', 'cpd15269', 'cpd00956', 'cpd03445', 'cpd03091', 'cpd11507', 'cpd10516', 'cpd00430', 'cpd14703', 'cpd00283', 'cpd12139', 'cpd15770', 'cpd00932', 'cpd11421', 'cpd00016', 'cpd02968', 'cpd15556', 'cpd03517', 'cpd00065', 'cpd15666', 'cpd00843', 'cpd02851', 'cpd15477', 'cpd00448', 'cpd02555', 'cpd15532', 'cpd02124', 'cpd02021', 'cpd03121', 'cpd11470', 'cpd11473', 'cpd02090', 'cpd00002', 'cpd00477', 'cpd33930', 'cpd21288', 'cpd02120', 'cpd00288', 'cpd00320', 'cpd12164', 'cpd00982', 'cpd15572', 'cpd03423', 'cpd02083', 'cpd00703', 'cpd00763', 'cpd00089', 'cpd00162', 'cpd00834', 'cpd15692', 'cpd11569', 'cpd00269', 'cpd00274', 'cpd12689', 'cpd00122', 'cpd15418', 'cpd03918', 'cpd02394', 'cpd15569', 'cpd15510', 'cpd00052', 'cpd11570', 'cpd00945', 'cpd03189', 'cpd02255', 'cpd15685', 'cpd19505', 'cpd00641', 'cpd00067', 'cpd00135', 'cpd06227', 'cpd00977', 'cpd01311', 'cpd21088', 'cpd00123', 'cpd00443', 'cpd00346', 'cpd15528', 'cpd00203', 'cpd04098', 'cpd03519', 'cpd00768', 'cpd00438', 'cpd03119', 'cpd15506', 'cpd03449', 'cpd00626', 'cpd11474', 'cpd12543', 'cpd11420', 'cpd15555', 'cpd03444', 'cpd15716', 'cpd11712', 'cpd11435', 'cpd00209', 'cpd12848', 'cpd22022', 'cpd00259', 'cpd00197', 'cpd00277', 'cpd00015', 'cpd02894', 'cpd01914', 'cpd00050', 'cpd15423', 'cpd15723', 'cpd15687', 'cpd00193', 'cpd27713', 'cpd11494', 'cpd11493', 'cpd00262', 'cpd00115', 'cpd00863', 'cpd00241', 'cpd11565', 'cpd15719', 'cpd15549', 'cpd00064', 'cpd00071', 'cpd03416', 'cpd11559', 'cpd21488', 'cpd01262', 'cpd00204', 'cpd15722', 'cpd11225', 'cpd03451', 'cpd15361', 'cpd00387', 'cpd14699', 'cpd00161', 'cpd15560', 'cpd11526', 'cpd15499', 'cpd22028', 'cpd00802', 'cpd03914', 'cpd12225', 'cpd00284', 'cpd15561', 'cpd11510', 'cpd03492', 'cpd00100', 'cpd11527', 'cpd00025', 'cpd01710', 'cpd00068', 'cpd02701', 'cpd00393', 'cpd02569', 'cpd02663', 'cpd11543', 'cpd15302', 'cpd03559', 'cpd00086', 'cpd00483', 'cpd04918', 'cpd15526', 'cpd00774', 'cpd00111', 'cpd00428', 'cpd15688', 'cpd00461', 'cpd01966', 'cpd00082', 'cpd14718', 'cpd02904', 'cpd15693', 'cpd15558', 'cpd00286', 'cpd02441', 'cpd02884', 'cpd00235', 'cpd11513', 'cpd03205', 'cpd15489', 'cpd00146', 'cpd03752', 'cpd00275', 'cpd15689', 'cpd02210', 'cpd02234', 'cpd15494', 'cpd00069', 'cpd15346', 'cpd15793', 'cpd00220', 'cpd00344', 'cpd00041', 'cpd00151', 'cpd11621', 'cpd02125', 'cpd03446', 'cpd03471', 'cpd11465', 'cpd22065', 'cpd00103', 'cpd00223', 'cpd15683', 'cpd11534', 'cpd00190', 'cpd02345', 'cpd00024', 'cpd03919', 'cpd00070', 'cpd00216', 'cpd00093', 'cpd02060', 'cpd01919', 'cpd11501', 'cpd02168', 'cpd00731', 'cpd15541', 'cpd00011', 'cpd15238', 'cpd21167', 'cpd15524', 'cpd00175', 'cpd00026', 'cpd15432', 'cpd00358', 'cpd15547', 'cpd02826', 'cpd03494', 'cpd02678', 'cpd00327', 'cpd00918', 'cpd00155', 'cpd15545', 'cpd15274', 'cpd33647', 'cpd11572', 'cpd32550', 'cpd03488', 'cpd11491', 'cpd02775', 'cpd03117', 'cpd01419', 'cpd01679', 'cpd00080', 'cpd15419', 'cpd00264', 'cpd11503', 'cpd15698', 'cpd08288', 'cpd03666', 'cpd00347', 'cpd02295', 'cpd02597', 'cpd02886', 'cpd03920', 'cpd01981', 'cpd15386', 'cpd15717', 'cpd00083', 'cpd26761', 'cpd27744', 'cpd15686', 'cpd00478', 'cpd11471', 'cpd00014', 'cpd11487', 'cpd00654', 'cpd02439', 'cpd00293', 'cpd11515', 'cpd01017', 'cpd00706', 'cpd11509', 'cpd00207', 'cpd11441', 'cpd00817', 'cpd01080', 'cpd11540', 'cpd01720', 'cpd00008', 'cpd00504', 'cpd02201', 'cpd02574', 'cpd00522', 'cpd15422', 'cpd04539', 'cpd11555', 'cpd11549', 'cpd11497', 'cpd00339', 'cpd11620', 'cpd00911', 'cpd02857', 'cpd11830', 'cpd11437', 'cpd11573', 'cpd11519', 'cpd15352', 'cpd15396', 'cpd02419', 'cpd00133', 'cpd17042', 'cpd00121', 'cpd00004', 'cpd00117', 'cpd00105', 'cpd03392', 'cpd00309', 'cpd03447', 'cpd03123', 'cpd00790', 'cpd15492', 'cpd02978', 'cpd11530', 'cpd00581', 'cpd00954', 'cpd08368', 'cpd01997', 'cpd02893', 'cpd15700', 'cpd01211', 'cpd15726', 'cpd00350', 'cpd00143', 'cpd00452', 'cpd02626', 'cpd03407', 'cpd03584', 'cpd11518', 'cpd35194', 'cpd00157', 'cpd15391', 'cpd15485', 'cpd00446', 'cpd00519', 'cpd15697', 'cpd00182', 'cpd03130', 'cpd00038', 'cpd03443', 'cpd02030', 'cpd00497', 'cpd00978', 'cpd15480', 'cpd00533', 'cpd26760', 'cpd11466', 'cpd00279', 'cpd02740', 'cpd03586', 'cpd00246', 'cpd02930', 'cpd02948', 'cpd21301', 'cpd03830', 'cpd00031', 'cpd01092', 'cpd02572', 'cpd00032', 'cpd15554', 'cpd15484', 'cpd08211', 'cpd00227', 'cpd00005', 'cpd00231', 'cpd00426', 'cpd15579', 'cpd11538', 'cpd11523', 'cpd00179', 'cpd02227', 'cpd00081', 'cpd00851', 'cpd02656', 'cpd11432', 'cpd11505', 'cpd00116', 'cpd02724', 'cpd15543', 'cpd00804', 'cpd14545', 'cpd00202', 'cpd00171', 'cpd00098', 'cpd00114', 'cpd15679', 'cpd00412', 'cpd15339', 'cpd02692', 'cpd01101', 'cpd01749', 'cpd03063', 'cpd27180', 'cpd11486', 'cpd03698', 'cpd21479', 'cpd00931', 'cpd15420', 'cpd00199', 'cpd00091', 'cpd02258', 'cpd03518', 'cpd11536', 'cpd03171', 'cpd00066', 'cpd00330', 'cpd21087', 'cpd00153', 'cpd15538', 'cpd02882', 'cpd22290', 'cpd10162', 'cpd02820', 'cpd04122', 'cpd00836', 'cpd28253', 'cpd00518', 'cpd15504', 'cpd11439', 'cpd02175', 'cpd15495', 'cpd00177', 'cpd00218', 'cpd03585', 'cpd00169', 'cpd15772', 'cpd00367', 'cpd15170', 'cpd02152', 'cpd15690', 'cpd03641', 'cpd02547', 'cpd02074', 'cpd15521', 'cpd00311', 'cpd00343', 'cpd15721', 'cpd09879', 'cpd02921', 'cpd15530', 'cpd15718', 'cpd15325', 'cpd00147', 'cpd15294', 'cpd15268', 'cpd11547', 'cpd00800', 'cpd02507', 'cpd02546', 'cpd11434', 'cpd00221', 'cpd11522', 'cpd21090', 'cpd00196', 'cpd00672', 'cpd02711', 'cpd15694', 'cpd11542', 'cpd00780', 'cpd11477', 'cpd00142', 'cpd00930', 'cpd15387', 'cpd15401', 'cpd02828', 'cpd03606', 'cpd01831', 'cpd00028', 'cpd15539', 'cpd00128', 'cpd03279', 'cpd00039', 'cpd00794', 'cpd02498', 'cpd00102', 'cpd00236', 'cpd00087', 'cpd09027', 'cpd15764', 'cpd01620', 'cpd15277', 'cpd15680', 'cpd00166', 'cpd11206', 'cpd14589', 'cpd03608', 'cpd11485', 'cpd11544', 'cpd03897', 'cpd03646', 'cpd00095', 'cpd01242', 'cpd00837', 'cpd00047', 'cpd00108', 'cpd03470', 'cpd00421', 'cpd00118', 'cpd00226', 'cpd00056', 'cpd15529', 'cpd11551', 'cpd00213', 'cpd01504', 'cpd00630', 'cpd27484', 'cpd02566', 'cpd00013', 'cpd03726', 'cpd03078', 'cpd15769', 'cpd00781', 'cpd15298', 'cpd03187', 'cpd00770', 'cpd00180', 'cpd11469', 'cpd02666', 'cpd00126', 'cpd15684', 'cpd00020', 'cpd15537', 'cpd00084', 'cpd11571', 'cpd00300', 'cpd03129', 'cpd21464', 'cpd01567', 'cpd00096', 'cpd00119', 'cpd15725', 'cpd00356', 'cpd08210', 'cpd15330', 'cpd00040', 'cpd00646', 'cpd00094', 'cpd00340', 'cpd03127', 'cpd00055', 'cpd11484', 'cpd00060', 'cpd03831', 'cpd00075', 'cpd03847', 'cpd10515', 'cpd02720', 'cpd15678', 'cpd15500', 'cpd11528', 'cpd00482', 'cpd01217', 'cpd02920', 'cpd15469', 'cpd00689', 'cpd00029', 'cpd00922', 'cpd11561', 'cpd03422', 'cpd15665', 'cpd03456', 'cpd19503', 'cpd00509', 'cpd01693', 'cpd00331', 'cpd00073', 'cpd00297', 'cpd02097', 'cpd19020', 'cpd00113', 'cpd00010', 'cpd02557', 'cpd15239', 'cpd03002', 'cpd00890', 'cpd00699', 'cpd03326', 'cpd00896', 'cpd11499', 'cpd02782', 'cpd22027', 'cpd01329', 'cpd36635', 'cpd02591', 'cpd00009', 'cpd00184', 'cpd01977', 'cpd00644', 'cpd00085', 'cpd15766', 'cpd11912', 'cpd00214', 'cpd15765', 'cpd02605', 'cpd01324', 'cpd00860', 'cpd15699', 'cpd00592', 'cpd15535', 'cpd00042', 'cpd15527', 'cpd27021', 'cpd00027', 'cpd00054', 'cpd11959', 'cpd02096', 'cpd03708', 'cpd02333', 'cpd11557', 'cpd00152', 'cpd00357', 'cpd00053', 'cpd00109', 'cpd00023', 'cpd00037', 'cpd03697', 'cpd11416', 'cpd00355', 'cpd08301', 'cpd15237', 'cpd15505', 'cpd03520', 'cpd21486', 'cpd00051', 'cpd15548', 'cpd01716', 'cpd00506', 'cpd00712', 'cpd00132', 'cpd00033', 'cpd04920', 'cpd00683', 'cpd15682', 'cpd17043', 'cpd02964', 'cpd15691', 'cpd00762', 'cpd03114', 'cpd02197', 'cpd15475', 'cpd15695', 'cpd02229', 'cpd01777', 'cpd21482', 'cpd03126', 'cpd00498', 'cpd15525', 'cpd11535', 'cpd15553', 'cpd08353', 'cpd15399', 'cpd03448', 'cpd00520', 'cpd03593', 'cpd02187', 'cpd11467', 'cpd00106', 'cpd00003', 'cpd00134', 'cpd00139', 'cpd17041', 'cpd15546', 'cpd00287', 'cpd00198', 'cpd00755', 'cpd00791', 'cpd28083', 'cpd00957', 'cpd11563', 'cpd14507', 'cpd03491', 'cpd26672', 'cpd00006', 'cpd00035', 'cpd00046', 'cpd00222', 'cpd11175', 'cpd15771', 'cpd00281', 'cpd02993', 'cpd00078', 'cpd03917', 'cpd15522', 'cpd15540', 'cpd00247', 'cpd03496', 'cpd03426', 'cpd15353', 'cpd00299', 'cpd15550', 'cpd00655', 'cpd00159', 'cpd01507', 'cpd11511', 'cpd00018', 'cpd03125', 'cpd00856', 'cpd00229', 'cpd03915', 'cpd11567', 'cpd15681', 'cpd00764', 'cpd01155', 'cpd02979', 'cpd00946', 'cpd08449', 'cpd11488', 'cpd11475', 'cpd00295', 'cpd11532', 'cpd00145', 'cpd00125', 'cpd02991', 'cpd08316', 'cpd00072', 'cpd00491', 'cpd00485', 'cpd02431', 'cpd00447', 'cpd18072', 'cpd00079', 'cpd00092', 'cpd03572', 'cpd09843', 'cpd00019', 'cpd00875', 'cpd03480', 'cpd02235', 'cpd15570', 'cpd15507', 'cpd00201', 'cpd11468', 'cpd00650', 'cpd01046', 'cpd27020', 'cpd00045', 'cpd01294', 'cpd00219', 'cpd15536', 'cpd02862', 'cpd11492', 'cpd00793', 'cpd00191', 'cpd01011', 'cpd00043', 'cpd00062', 'cpd08615', 'cpd02552', 'cpd15557', 'cpd11489', 'cpd15720', 'cpd00178', 'cpd00107', 'cpd12370', 'cpd11517', 'cpd00104', 'cpd15696', 'cpd08287', 'cpd00321', 'cpd02590', 'cpd02700', 'cpd00906', 'cpd02731', 'cpd02140', 'cpd15327', 'cpd00658', 'cpd00465'}\n", - "cpd11416_c0 bio1: 0.5 cpd11416_c1 + 0.5 cpd11416_c2 --> cpd11416_c0;\tcpd11416_c0 SK_cpd11416_c0: cpd11416_c0 <=> ;\tMainProcess~~1\t['Pseudomonas_sp._GM17_2511231006.fna.RAST.fbamodel', 'Sphingobium_sp._AP49_2512564014.fna.RAST.fbamodel']\n", - "{'cpd00215', 'cpd00209', 'cpd00654', 'cpd00149', 'cpd00307', 'cpd00030', 'cpd00007', 'cpd03847', 'cpd01017', 'cpd00644', 'cpd10515', 'cpd00311', 'cpd01080', 'cpd00793', 'cpd00156', 'cpd00205', 'cpd00322', 'cpd00069', 'cpd00063', 'cpd00107', 'cpd00220', 'cpd00104', 'cpd00099', 'cpd00065', 'cpd00066', 'cpd00264', 'cpd00017', 'cpd00048', 'cpd00355', 'cpd00438', 'cpd00034', 'cpd00028', 'cpd00393', 'cpd00254', 'cpd00179', 'cpd00119', 'cpd00051', 'cpd00136', 'cpd00058'}\n", - "{'cpd03736', 'cpd11524', 'cpd00900', 'cpd19019', 'cpd00036', 'cpd15533', 'cpd00176', 'cpd02961', 'cpd11553', 'cpd00658', 'cpd00722', 'cpd02465', 'cpd00144', 'cpd00868', 'cpd08289', 'cpd00638', 'cpd03833', 'cpd03704', 'cpd00200', 'cpd00012', 'cpd07924', 'cpd15417', 'cpd03495', 'cpd00876', 'cpd15531', 'cpd00298', 'cpd15479', 'cpd15552', 'cpd03211', 'cpd00249', 'cpd02069', 'cpd00521', 'cpd36025', 'cpd00022', 'cpd00017', 'cpd00809', 'cpd00525', 'cpd00359', 'cpd00516', 'cpd00873', 'cpd15358', 'cpd15421', 'cpd03916', 'cpd12227', 'cpd11490', 'cpd02375', 'cpd00129', 'cpd00759', 'cpd02501', 'cpd01695', 'cpd00001', 'cpd02068', 'cpd01741', 'cpd15544', 'cpd15488', 'cpd03839', 'cpd02016', 'cpd00341', 'cpd01399', 'cpd15534', 'cpd11310', 'cpd00101', 'cpd03524', 'cpd00007', 'cpd00501', 'cpd11498', 'cpd15542', 'cpd11313', 'cpd00508', 'cpd00186', 'cpd00908', 'cpd11217', 'cpd00061', 'cpd02611', 'cpd00523', 'cpd15269', 'cpd00956', 'cpd03445', 'cpd03091', 'cpd11507', 'cpd10516', 'cpd14703', 'cpd00283', 'cpd12139', 'cpd00932', 'cpd11421', 'cpd00016', 'cpd02968', 'cpd15556', 'cpd03517', 'cpd00437', 'cpd00065', 'cpd01441', 'cpd15666', 'cpd00843', 'cpd02851', 'cpd15477', 'cpd00448', 'cpd15532', 'cpd02124', 'cpd02021', 'cpd03121', 'cpd11473', 'cpd02090', 'cpd00002', 'cpd00477', 'cpd33930', 'cpd21288', 'cpd02120', 'cpd00288', 'cpd00320', 'cpd03423', 'cpd00982', 'cpd15572', 'cpd02083', 'cpd00763', 'cpd00089', 'cpd00162', 'cpd00834', 'cpd15692', 'cpd11569', 'cpd00274', 'cpd00122', 'cpd12689', 'cpd15418', 'cpd03918', 'cpd02394', 'cpd15569', 'cpd00052', 'cpd11570', 'cpd00945', 'cpd03189', 'cpd02255', 'cpd00424', 'cpd00649', 'cpd15685', 'cpd19505', 'cpd00641', 'cpd00067', 'cpd00135', 'cpd00338', 'cpd06227', 'cpd00977', 'cpd01311', 'cpd21088', 'cpd00123', 'cpd00443', 'cpd00346', 'cpd15528', 'cpd00203', 'cpd03519', 'cpd00768', 'cpd00438', 'cpd03119', 'cpd15506', 'cpd03449', 'cpd03913', 'cpd11474', 'cpd15555', 'cpd12543', 'cpd11420', 'cpd03444', 'cpd00626', 'cpd15716', 'cpd11435', 'cpd00209', 'cpd12848', 'cpd22022', 'cpd00197', 'cpd00277', 'cpd00015', 'cpd02894', 'cpd01914', 'cpd00050', 'cpd15423', 'cpd15687', 'cpd00193', 'cpd27713', 'cpd11494', 'cpd11493', 'cpd00115', 'cpd15549', 'cpd00241', 'cpd11565', 'cpd15719', 'cpd00064', 'cpd00071', 'cpd03416', 'cpd11559', 'cpd21488', 'cpd20412', 'cpd01262', 'cpd00204', 'cpd00492', 'cpd11225', 'cpd03451', 'cpd15361', 'cpd00387', 'cpd14699', 'cpd00161', 'cpd15560', 'cpd11526', 'cpd15499', 'cpd22028', 'cpd00802', 'cpd03914', 'cpd12225', 'cpd00284', 'cpd15561', 'cpd11510', 'cpd03492', 'cpd00100', 'cpd11527', 'cpd00025', 'cpd01710', 'cpd00068', 'cpd02701', 'cpd00393', 'cpd02569', 'cpd02663', 'cpd11543', 'cpd15302', 'cpd03732', 'cpd03559', 'cpd00086', 'cpd04918', 'cpd00774', 'cpd02506', 'cpd00111', 'cpd00428', 'cpd15688', 'cpd01966', 'cpd00082', 'cpd00986', 'cpd02103', 'cpd14718', 'cpd02904', 'cpd15693', 'cpd15558', 'cpd00286', 'cpd02441', 'cpd02884', 'cpd00235', 'cpd11513', 'cpd00382', 'cpd03205', 'cpd15489', 'cpd00146', 'cpd03752', 'cpd09254', 'cpd00077', 'cpd00275', 'cpd15689', 'cpd02210', 'cpd02234', 'cpd00069', 'cpd15388', 'cpd00233', 'cpd15793', 'cpd00220', 'cpd01562', 'cpd00344', 'cpd00041', 'cpd11621', 'cpd02125', 'cpd03446', 'cpd03471', 'cpd11465', 'cpd22065', 'cpd00103', 'cpd00223', 'cpd15683', 'cpd11534', 'cpd00190', 'cpd00897', 'cpd00024', 'cpd03919', 'cpd00070', 'cpd00216', 'cpd00093', 'cpd02060', 'cpd01919', 'cpd11501', 'cpd02168', 'cpd02143', 'cpd00731', 'cpd00011', 'cpd15238', 'cpd00026', 'cpd15432', 'cpd00358', 'cpd15547', 'cpd02826', 'cpd03494', 'cpd02678', 'cpd00327', 'cpd00918', 'cpd00155', 'cpd15545', 'cpd15274', 'cpd11572', 'cpd03488', 'cpd11491', 'cpd02775', 'cpd03117', 'cpd00080', 'cpd15419', 'cpd00264', 'cpd11503', 'cpd15698', 'cpd03832', 'cpd08288', 'cpd03666', 'cpd00347', 'cpd02295', 'cpd00861', 'cpd02886', 'cpd03920', 'cpd01981', 'cpd15386', 'cpd15717', 'cpd03525', 'cpd00083', 'cpd27744', 'cpd15686', 'cpd00478', 'cpd11471', 'cpd00014', 'cpd11487', 'cpd00654', 'cpd00293', 'cpd11515', 'cpd01017', 'cpd00706', 'cpd11509', 'cpd00207', 'cpd11441', 'cpd00817', 'cpd01080', 'cpd11540', 'cpd00008', 'cpd00504', 'cpd02201', 'cpd15422', 'cpd04539', 'cpd11555', 'cpd11549', 'cpd11497', 'cpd00522', 'cpd00339', 'cpd11620', 'cpd00911', 'cpd02857', 'cpd11830', 'cpd11437', 'cpd11519', 'cpd15352', 'cpd15396', 'cpd02419', 'cpd17042', 'cpd00121', 'cpd00004', 'cpd00117', 'cpd00105', 'cpd03392', 'cpd00309', 'cpd03447', 'cpd03123', 'cpd00790', 'cpd15492', 'cpd02978', 'cpd11530', 'cpd00324', 'cpd00581', 'cpd14698', 'cpd00954', 'cpd19442', 'cpd01997', 'cpd02893', 'cpd15700', 'cpd14700', 'cpd00350', 'cpd00143', 'cpd03407', 'cpd03584', 'cpd11518', 'cpd00157', 'cpd15391', 'cpd15485', 'cpd00519', 'cpd15697', 'cpd00182', 'cpd03130', 'cpd00038', 'cpd03443', 'cpd02030', 'cpd00497', 'cpd00978', 'cpd00533', 'cpd03420', 'cpd00279', 'cpd02740', 'cpd03586', 'cpd00246', 'cpd02930', 'cpd02948', 'cpd03830', 'cpd00031', 'cpd01092', 'cpd00032', 'cpd15554', 'cpd15484', 'cpd08211', 'cpd03835', 'cpd00005', 'cpd00231', 'cpd00426', 'cpd11538', 'cpd11523', 'cpd00179', 'cpd02227', 'cpd00081', 'cpd00851', 'cpd02656', 'cpd11432', 'cpd11505', 'cpd00116', 'cpd02724', 'cpd15543', 'cpd00804', 'cpd00202', 'cpd12005', 'cpd00171', 'cpd00098', 'cpd00114', 'cpd00412', 'cpd02692', 'cpd01101', 'cpd27180', 'cpd11486', 'cpd01630', 'cpd03762', 'cpd03698', 'cpd21479', 'cpd00931', 'cpd15420', 'cpd00091', 'cpd02258', 'cpd03518', 'cpd11536', 'cpd00066', 'cpd00330', 'cpd21087', 'cpd02882', 'cpd22290', 'cpd10162', 'cpd02820', 'cpd04122', 'cpd00836', 'cpd28253', 'cpd00518', 'cpd11439', 'cpd18078', 'cpd02175', 'cpd15495', 'cpd00177', 'cpd00218', 'cpd03585', 'cpd00169', 'cpd00367', 'cpd15170', 'cpd02152', 'cpd15690', 'cpd03641', 'cpd02547', 'cpd01879', 'cpd00311', 'cpd00343', 'cpd15721', 'cpd09879', 'cpd02921', 'cpd15530', 'cpd15718', 'cpd15325', 'cpd00147', 'cpd15294', 'cpd15268', 'cpd11547', 'cpd00800', 'cpd02546', 'cpd11434', 'cpd00221', 'cpd11522', 'cpd00672', 'cpd02711', 'cpd15694', 'cpd11542', 'cpd00780', 'cpd11477', 'cpd00142', 'cpd00930', 'cpd15387', 'cpd15401', 'cpd03606', 'cpd01831', 'cpd00028', 'cpd00128', 'cpd03279', 'cpd00039', 'cpd00794', 'cpd02498', 'cpd00102', 'cpd00236', 'cpd00087', 'cpd01620', 'cpd00166', 'cpd11206', 'cpd03608', 'cpd11485', 'cpd11544', 'cpd03897', 'cpd03646', 'cpd00296', 'cpd00095', 'cpd00047', 'cpd00108', 'cpd03470', 'cpd00421', 'cpd00118', 'cpd00226', 'cpd00056', 'cpd15529', 'cpd11551', 'cpd00213', 'cpd01504', 'cpd00630', 'cpd27484', 'cpd00013', 'cpd03726', 'cpd15298', 'cpd03187', 'cpd00770', 'cpd00180', 'cpd03834', 'cpd11469', 'cpd02666', 'cpd00126', 'cpd15684', 'cpd00020', 'cpd00084', 'cpd11571', 'cpd03129', 'cpd00300', 'cpd21464', 'cpd01567', 'cpd00096', 'cpd00119', 'cpd00356', 'cpd00076', 'cpd08210', 'cpd15330', 'cpd00040', 'cpd00646', 'cpd00094', 'cpd00340', 'cpd03127', 'cpd00055', 'cpd11484', 'cpd00060', 'cpd03831', 'cpd00075', 'cpd03847', 'cpd10515', 'cpd02720', 'cpd15500', 'cpd11528', 'cpd01217', 'cpd02920', 'cpd15469', 'cpd00689', 'cpd00029', 'cpd00922', 'cpd11561', 'cpd03422', 'cpd15665', 'cpd19503', 'cpd01693', 'cpd00331', 'cpd00297', 'cpd02097', 'cpd00113', 'cpd00010', 'cpd15239', 'cpd03002', 'cpd00890', 'cpd00699', 'cpd11499', 'cpd22027', 'cpd00390', 'cpd36635', 'cpd00009', 'cpd00184', 'cpd01977', 'cpd00644', 'cpd00214', 'cpd02605', 'cpd01324', 'cpd00860', 'cpd15699', 'cpd27021', 'cpd00042', 'cpd15527', 'cpd00027', 'cpd00054', 'cpd02333', 'cpd11557', 'cpd03198', 'cpd03813', 'cpd00357', 'cpd00053', 'cpd00109', 'cpd00023', 'cpd00037', 'cpd03697', 'cpd03220', 'cpd00355', 'cpd08301', 'cpd15237', 'cpd15505', 'cpd03520', 'cpd21486', 'cpd11416', 'cpd00051', 'cpd01716', 'cpd15548', 'cpd00506', 'cpd00132', 'cpd00712', 'cpd00033', 'cpd00044', 'cpd04920', 'cpd00683', 'cpd17043', 'cpd02964', 'cpd15691', 'cpd03114', 'cpd02197', 'cpd15475', 'cpd15695', 'cpd02229', 'cpd01777', 'cpd21482', 'cpd03126', 'cpd00498', 'cpd11535', 'cpd00239', 'cpd15553', 'cpd15399', 'cpd03448', 'cpd03593', 'cpd02187', 'cpd11467', 'cpd00106', 'cpd00003', 'cpd00134', 'cpd00139', 'cpd17041', 'cpd15546', 'cpd00287', 'cpd00198', 'cpd00755', 'cpd00791', 'cpd28083', 'cpd00957', 'cpd11563', 'cpd14507', 'cpd03491', 'cpd26672', 'cpd00006', 'cpd00035', 'cpd00046', 'cpd00222', 'cpd00281', 'cpd02993', 'cpd00078', 'cpd03917', 'cpd02160', 'cpd02338', 'cpd15522', 'cpd03496', 'cpd00247', 'cpd15540', 'cpd03426', 'cpd02967', 'cpd15353', 'cpd00299', 'cpd15550', 'cpd00655', 'cpd01507', 'cpd14720', 'cpd11511', 'cpd00018', 'cpd03125', 'cpd00229', 'cpd11567', 'cpd00764', 'cpd22312', 'cpd02979', 'cpd08449', 'cpd11488', 'cpd11475', 'cpd00295', 'cpd11532', 'cpd00145', 'cpd00125', 'cpd02991', 'cpd08316', 'cpd00072', 'cpd00491', 'cpd00485', 'cpd02431', 'cpd00447', 'cpd18072', 'cpd00079', 'cpd00092', 'cpd03572', 'cpd00019', 'cpd00875', 'cpd03480', 'cpd15570', 'cpd15507', 'cpd00201', 'cpd11468', 'cpd00650', 'cpd01046', 'cpd03761', 'cpd27020', 'cpd00045', 'cpd00219', 'cpd02862', 'cpd11492', 'cpd00793', 'cpd00191', 'cpd08615', 'cpd00043', 'cpd00062', 'cpd02552', 'cpd15557', 'cpd11489', 'cpd01527', 'cpd15720', 'cpd00107', 'cpd12370', 'cpd11517', 'cpd00104', 'cpd15696', 'cpd08287', 'cpd02590', 'cpd00224', 'cpd02700', 'cpd14702', 'cpd02140', 'cpd15327', 'cpd21480', 'cpd11466'}\n", - "cpd11416_c0 bio1: 0.5 cpd11416_c1 + 0.5 cpd11416_c2 --> cpd11416_c0;\tcpd11416_c0 SK_cpd11416_c0: cpd11416_c0 <=> ;\tMainProcess~~2\t['Variovorax_sp._CF313_2513020051.fna.RAST.fbamodel', 'Sphingobium_sp._AP49_2512564014.fna.RAST.fbamodel']\n", - "{'cpd00215', 'cpd00209', 'cpd00149', 'cpd00051', 'cpd00307', 'cpd00030', 'cpd00007', 'cpd00644', 'cpd10515', 'cpd00793', 'cpd00156', 'cpd00205', 'cpd00322', 'cpd00069', 'cpd00063', 'cpd00042', 'cpd00107', 'cpd00220', 'cpd00104', 'cpd00099', 'cpd00065', 'cpd00066', 'cpd00017', 'cpd00048', 'cpd00355', 'cpd00393', 'cpd00028', 'cpd00794', 'cpd00254', 'cpd00119', 'cpd00034', 'cpd00136', 'cpd00058'}\n", - "{'cpd03736', 'cpd11524', 'cpd00900', 'cpd19019', 'cpd00036', 'cpd15533', 'cpd00176', 'cpd02961', 'cpd11553', 'cpd00658', 'cpd00722', 'cpd02465', 'cpd00144', 'cpd00868', 'cpd08289', 'cpd00638', 'cpd03833', 'cpd03704', 'cpd00200', 'cpd00012', 'cpd07924', 'cpd15417', 'cpd03495', 'cpd00876', 'cpd15531', 'cpd00298', 'cpd15479', 'cpd15552', 'cpd03211', 'cpd00249', 'cpd02069', 'cpd00521', 'cpd36025', 'cpd00022', 'cpd00017', 'cpd00809', 'cpd00525', 'cpd00359', 'cpd00516', 'cpd00873', 'cpd15358', 'cpd15421', 'cpd03916', 'cpd12227', 'cpd11490', 'cpd02375', 'cpd00129', 'cpd00759', 'cpd02501', 'cpd01695', 'cpd00001', 'cpd02068', 'cpd01741', 'cpd15544', 'cpd15488', 'cpd03839', 'cpd02016', 'cpd00341', 'cpd01399', 'cpd15534', 'cpd11310', 'cpd00101', 'cpd03524', 'cpd00007', 'cpd00501', 'cpd11498', 'cpd15542', 'cpd11313', 'cpd00508', 'cpd00186', 'cpd00908', 'cpd11217', 'cpd00061', 'cpd02611', 'cpd00523', 'cpd15269', 'cpd00956', 'cpd03445', 'cpd03091', 'cpd11507', 'cpd10516', 'cpd14703', 'cpd00283', 'cpd12139', 'cpd00932', 'cpd11421', 'cpd00016', 'cpd02968', 'cpd15556', 'cpd03517', 'cpd00437', 'cpd00065', 'cpd01441', 'cpd15666', 'cpd00843', 'cpd02851', 'cpd15477', 'cpd00448', 'cpd15532', 'cpd02124', 'cpd02021', 'cpd03121', 'cpd11473', 'cpd02090', 'cpd00002', 'cpd00477', 'cpd33930', 'cpd21288', 'cpd02120', 'cpd00288', 'cpd00320', 'cpd03423', 'cpd00982', 'cpd15572', 'cpd02083', 'cpd00763', 'cpd00089', 'cpd00162', 'cpd00834', 'cpd15692', 'cpd11569', 'cpd00274', 'cpd00122', 'cpd12689', 'cpd15418', 'cpd03918', 'cpd02394', 'cpd15569', 'cpd00052', 'cpd11570', 'cpd00945', 'cpd03189', 'cpd02255', 'cpd00424', 'cpd00649', 'cpd15685', 'cpd19505', 'cpd00641', 'cpd00067', 'cpd00135', 'cpd00338', 'cpd06227', 'cpd00977', 'cpd01311', 'cpd21088', 'cpd00123', 'cpd00443', 'cpd00346', 'cpd15528', 'cpd00203', 'cpd03519', 'cpd00768', 'cpd00438', 'cpd03119', 'cpd15506', 'cpd03449', 'cpd03913', 'cpd11474', 'cpd15555', 'cpd12543', 'cpd11420', 'cpd03444', 'cpd00626', 'cpd15716', 'cpd11435', 'cpd00209', 'cpd12848', 'cpd22022', 'cpd00197', 'cpd00277', 'cpd00015', 'cpd02894', 'cpd01914', 'cpd00050', 'cpd15423', 'cpd15687', 'cpd00193', 'cpd27713', 'cpd11494', 'cpd11493', 'cpd00115', 'cpd15549', 'cpd00241', 'cpd11565', 'cpd15719', 'cpd00064', 'cpd00071', 'cpd03416', 'cpd11559', 'cpd21488', 'cpd20412', 'cpd01262', 'cpd00204', 'cpd00492', 'cpd11225', 'cpd03451', 'cpd15361', 'cpd00387', 'cpd14699', 'cpd00161', 'cpd15560', 'cpd11526', 'cpd15499', 'cpd22028', 'cpd00802', 'cpd03914', 'cpd12225', 'cpd00284', 'cpd15561', 'cpd11510', 'cpd03492', 'cpd00100', 'cpd11527', 'cpd00025', 'cpd01710', 'cpd00068', 'cpd02701', 'cpd00393', 'cpd02569', 'cpd02663', 'cpd11543', 'cpd15302', 'cpd03732', 'cpd03559', 'cpd00086', 'cpd04918', 'cpd00774', 'cpd02506', 'cpd00111', 'cpd00428', 'cpd15688', 'cpd01966', 'cpd00082', 'cpd00986', 'cpd02103', 'cpd14718', 'cpd02904', 'cpd15693', 'cpd15558', 'cpd00286', 'cpd02441', 'cpd02884', 'cpd00235', 'cpd11513', 'cpd00382', 'cpd03205', 'cpd15489', 'cpd00146', 'cpd03752', 'cpd09254', 'cpd00077', 'cpd00275', 'cpd15689', 'cpd02210', 'cpd02234', 'cpd00069', 'cpd15388', 'cpd00233', 'cpd15793', 'cpd00220', 'cpd01562', 'cpd00344', 'cpd00041', 'cpd11621', 'cpd02125', 'cpd03446', 'cpd03471', 'cpd11465', 'cpd22065', 'cpd00103', 'cpd00223', 'cpd15683', 'cpd11534', 'cpd00190', 'cpd00897', 'cpd00024', 'cpd03919', 'cpd00070', 'cpd00216', 'cpd00093', 'cpd02060', 'cpd01919', 'cpd11501', 'cpd02168', 'cpd02143', 'cpd00731', 'cpd00011', 'cpd15238', 'cpd00026', 'cpd15432', 'cpd00358', 'cpd15547', 'cpd02826', 'cpd03494', 'cpd02678', 'cpd00327', 'cpd00918', 'cpd00155', 'cpd15545', 'cpd15274', 'cpd11572', 'cpd03488', 'cpd11491', 'cpd02775', 'cpd03117', 'cpd00080', 'cpd15419', 'cpd00264', 'cpd11503', 'cpd15698', 'cpd03832', 'cpd08288', 'cpd03666', 'cpd00347', 'cpd02295', 'cpd00861', 'cpd02886', 'cpd03920', 'cpd01981', 'cpd15386', 'cpd15717', 'cpd03525', 'cpd00083', 'cpd27744', 'cpd15686', 'cpd00478', 'cpd11471', 'cpd00014', 'cpd11487', 'cpd00654', 'cpd00293', 'cpd11515', 'cpd01017', 'cpd00706', 'cpd11509', 'cpd00207', 'cpd11441', 'cpd00817', 'cpd01080', 'cpd11540', 'cpd00008', 'cpd00504', 'cpd02201', 'cpd15422', 'cpd04539', 'cpd11555', 'cpd11549', 'cpd11497', 'cpd00522', 'cpd00339', 'cpd11620', 'cpd00911', 'cpd02857', 'cpd11830', 'cpd11437', 'cpd11519', 'cpd15352', 'cpd15396', 'cpd02419', 'cpd17042', 'cpd00121', 'cpd00004', 'cpd00117', 'cpd00105', 'cpd03392', 'cpd00309', 'cpd03447', 'cpd03123', 'cpd00790', 'cpd15492', 'cpd02978', 'cpd11530', 'cpd00324', 'cpd00581', 'cpd14698', 'cpd00954', 'cpd19442', 'cpd01997', 'cpd02893', 'cpd15700', 'cpd14700', 'cpd00350', 'cpd00143', 'cpd03407', 'cpd03584', 'cpd11518', 'cpd00157', 'cpd15391', 'cpd15485', 'cpd00519', 'cpd15697', 'cpd00182', 'cpd03130', 'cpd00038', 'cpd03443', 'cpd02030', 'cpd00497', 'cpd00978', 'cpd00533', 'cpd03420', 'cpd00279', 'cpd02740', 'cpd03586', 'cpd00246', 'cpd02930', 'cpd02948', 'cpd03830', 'cpd00031', 'cpd01092', 'cpd00032', 'cpd15554', 'cpd15484', 'cpd08211', 'cpd03835', 'cpd00005', 'cpd00231', 'cpd00426', 'cpd11538', 'cpd11523', 'cpd00179', 'cpd02227', 'cpd00081', 'cpd00851', 'cpd02656', 'cpd11432', 'cpd11505', 'cpd00116', 'cpd02724', 'cpd15543', 'cpd00804', 'cpd00202', 'cpd12005', 'cpd00171', 'cpd00098', 'cpd00114', 'cpd00412', 'cpd02692', 'cpd01101', 'cpd27180', 'cpd11486', 'cpd01630', 'cpd03762', 'cpd03698', 'cpd21479', 'cpd00931', 'cpd15420', 'cpd00091', 'cpd02258', 'cpd03518', 'cpd11536', 'cpd00066', 'cpd00330', 'cpd21087', 'cpd02882', 'cpd22290', 'cpd10162', 'cpd02820', 'cpd04122', 'cpd00836', 'cpd28253', 'cpd00518', 'cpd11439', 'cpd18078', 'cpd02175', 'cpd15495', 'cpd00177', 'cpd00218', 'cpd03585', 'cpd00169', 'cpd00367', 'cpd15170', 'cpd02152', 'cpd15690', 'cpd03641', 'cpd02547', 'cpd01879', 'cpd00311', 'cpd00343', 'cpd15721', 'cpd09879', 'cpd02921', 'cpd15530', 'cpd15718', 'cpd15325', 'cpd00147', 'cpd15294', 'cpd15268', 'cpd11547', 'cpd00800', 'cpd02546', 'cpd11434', 'cpd00221', 'cpd11522', 'cpd00672', 'cpd02711', 'cpd15694', 'cpd11542', 'cpd00780', 'cpd11477', 'cpd00142', 'cpd00930', 'cpd15387', 'cpd15401', 'cpd03606', 'cpd01831', 'cpd00028', 'cpd00128', 'cpd03279', 'cpd00039', 'cpd00794', 'cpd02498', 'cpd00102', 'cpd00236', 'cpd00087', 'cpd01620', 'cpd00166', 'cpd11206', 'cpd03608', 'cpd11485', 'cpd11544', 'cpd03897', 'cpd03646', 'cpd00296', 'cpd00095', 'cpd00047', 'cpd00108', 'cpd03470', 'cpd00421', 'cpd00118', 'cpd00226', 'cpd00056', 'cpd15529', 'cpd11551', 'cpd00213', 'cpd01504', 'cpd00630', 'cpd27484', 'cpd00013', 'cpd03726', 'cpd15298', 'cpd03187', 'cpd00770', 'cpd00180', 'cpd03834', 'cpd11469', 'cpd02666', 'cpd00126', 'cpd15684', 'cpd00020', 'cpd00084', 'cpd11571', 'cpd03129', 'cpd00300', 'cpd21464', 'cpd01567', 'cpd00096', 'cpd00119', 'cpd00356', 'cpd00076', 'cpd08210', 'cpd15330', 'cpd00040', 'cpd00646', 'cpd00094', 'cpd00340', 'cpd03127', 'cpd00055', 'cpd11484', 'cpd00060', 'cpd03831', 'cpd00075', 'cpd03847', 'cpd10515', 'cpd02720', 'cpd15500', 'cpd11528', 'cpd01217', 'cpd02920', 'cpd15469', 'cpd00689', 'cpd00029', 'cpd00922', 'cpd11561', 'cpd03422', 'cpd15665', 'cpd19503', 'cpd01693', 'cpd00331', 'cpd00297', 'cpd02097', 'cpd00113', 'cpd00010', 'cpd15239', 'cpd03002', 'cpd00890', 'cpd00699', 'cpd11499', 'cpd22027', 'cpd00390', 'cpd36635', 'cpd00009', 'cpd00184', 'cpd01977', 'cpd00644', 'cpd00214', 'cpd02605', 'cpd01324', 'cpd00860', 'cpd15699', 'cpd27021', 'cpd00042', 'cpd15527', 'cpd00027', 'cpd00054', 'cpd02333', 'cpd11557', 'cpd03198', 'cpd03813', 'cpd00357', 'cpd00053', 'cpd00109', 'cpd00023', 'cpd00037', 'cpd03697', 'cpd03220', 'cpd00355', 'cpd08301', 'cpd15237', 'cpd15505', 'cpd03520', 'cpd21486', 'cpd11416', 'cpd00051', 'cpd01716', 'cpd15548', 'cpd00506', 'cpd00132', 'cpd00712', 'cpd00033', 'cpd00044', 'cpd04920', 'cpd00683', 'cpd17043', 'cpd02964', 'cpd15691', 'cpd03114', 'cpd02197', 'cpd15475', 'cpd15695', 'cpd02229', 'cpd01777', 'cpd21482', 'cpd03126', 'cpd00498', 'cpd11535', 'cpd00239', 'cpd15553', 'cpd15399', 'cpd03448', 'cpd03593', 'cpd02187', 'cpd11467', 'cpd00106', 'cpd00003', 'cpd00134', 'cpd00139', 'cpd17041', 'cpd15546', 'cpd00287', 'cpd00198', 'cpd00755', 'cpd00791', 'cpd28083', 'cpd00957', 'cpd11563', 'cpd14507', 'cpd03491', 'cpd26672', 'cpd00006', 'cpd00035', 'cpd00046', 'cpd00222', 'cpd00281', 'cpd02993', 'cpd00078', 'cpd03917', 'cpd02160', 'cpd02338', 'cpd15522', 'cpd03496', 'cpd00247', 'cpd15540', 'cpd03426', 'cpd02967', 'cpd15353', 'cpd00299', 'cpd15550', 'cpd00655', 'cpd01507', 'cpd14720', 'cpd11511', 'cpd00018', 'cpd03125', 'cpd00229', 'cpd11567', 'cpd00764', 'cpd22312', 'cpd02979', 'cpd08449', 'cpd11488', 'cpd11475', 'cpd00295', 'cpd11532', 'cpd00145', 'cpd00125', 'cpd02991', 'cpd08316', 'cpd00072', 'cpd00491', 'cpd00485', 'cpd02431', 'cpd00447', 'cpd18072', 'cpd00079', 'cpd00092', 'cpd03572', 'cpd00019', 'cpd00875', 'cpd03480', 'cpd15570', 'cpd15507', 'cpd00201', 'cpd11468', 'cpd00650', 'cpd01046', 'cpd03761', 'cpd27020', 'cpd00045', 'cpd00219', 'cpd02862', 'cpd11492', 'cpd00793', 'cpd00191', 'cpd08615', 'cpd00043', 'cpd00062', 'cpd02552', 'cpd15557', 'cpd11489', 'cpd01527', 'cpd15720', 'cpd00107', 'cpd12370', 'cpd11517', 'cpd00104', 'cpd15696', 'cpd08287', 'cpd02590', 'cpd00224', 'cpd02700', 'cpd14702', 'cpd02140', 'cpd15327', 'cpd21480', 'cpd11466'}\n" - ] - }, - { - "ename": "ValueError", - "evalue": "could not convert string to float: '9 (0)'", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[2], line 17\u001b[0m\n\u001b[0;32m 15\u001b[0m media \u001b[38;5;241m=\u001b[39m [kbase_api\u001b[38;5;241m.\u001b[39mget_from_ws(medium) \u001b[38;5;28;01mfor\u001b[39;00m medium \u001b[38;5;129;01min\u001b[39;00m media_objs]\n\u001b[0;32m 16\u001b[0m df, mets \u001b[38;5;241m=\u001b[39m MSCommScores\u001b[38;5;241m.\u001b[39mkbase_output(models, kbase_obj\u001b[38;5;241m=\u001b[39mkbase_api, environments\u001b[38;5;241m=\u001b[39mmedia)\n\u001b[1;32m---> 17\u001b[0m reportHTML \u001b[38;5;241m=\u001b[39m \u001b[43mcommscores_report\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdf\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmets\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mindex_html_path\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\modelseedpy\\core\\report.py:213\u001b[0m, in \u001b[0;36mcommscores_report\u001b[1;34m(df, mets, export_html_path)\u001b[0m\n\u001b[0;32m 211\u001b[0m heatmap_df[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmro_model1\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m heatmap_df[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmro_model1\u001b[39m\u001b[38;5;124m\"\u001b[39m]\u001b[38;5;241m.\u001b[39mapply(quantify_MRO)\n\u001b[0;32m 212\u001b[0m heatmap_df[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmro_model2\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m heatmap_df[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmro_model2\u001b[39m\u001b[38;5;124m\"\u001b[39m]\u001b[38;5;241m.\u001b[39mapply(quantify_MRO)\n\u001b[1;32m--> 213\u001b[0m heatmap_df \u001b[38;5;241m=\u001b[39m \u001b[43mheatmap_df\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mastype\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mfloat\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m 214\u001b[0m heatmap_df[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmip\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m heatmap_df[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmip\u001b[39m\u001b[38;5;124m\"\u001b[39m]\u001b[38;5;241m.\u001b[39mastype(\u001b[38;5;28mint\u001b[39m)\n\u001b[0;32m 215\u001b[0m \u001b[38;5;66;03m# populate the HTML template with the assembled simulation data from the DataFrame -> HTML conversion\u001b[39;00m\n", - "File \u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\pandas\\core\\generic.py:6240\u001b[0m, in \u001b[0;36mNDFrame.astype\u001b[1;34m(self, dtype, copy, errors)\u001b[0m\n\u001b[0;32m 6233\u001b[0m results \u001b[38;5;241m=\u001b[39m [\n\u001b[0;32m 6234\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39miloc[:, i]\u001b[38;5;241m.\u001b[39mastype(dtype, copy\u001b[38;5;241m=\u001b[39mcopy)\n\u001b[0;32m 6235\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(\u001b[38;5;28mlen\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcolumns))\n\u001b[0;32m 6236\u001b[0m ]\n\u001b[0;32m 6238\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 6239\u001b[0m \u001b[38;5;66;03m# else, only a single dtype is given\u001b[39;00m\n\u001b[1;32m-> 6240\u001b[0m new_data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_mgr\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mastype\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdtype\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdtype\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcopy\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcopy\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43merrors\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43merrors\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 6241\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_constructor(new_data)\u001b[38;5;241m.\u001b[39m__finalize__(\u001b[38;5;28mself\u001b[39m, method\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mastype\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 6243\u001b[0m \u001b[38;5;66;03m# GH 33113: handle empty frame or series\u001b[39;00m\n", - "File \u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\pandas\\core\\internals\\managers.py:450\u001b[0m, in \u001b[0;36mBaseBlockManager.astype\u001b[1;34m(self, dtype, copy, errors)\u001b[0m\n\u001b[0;32m 449\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mastype\u001b[39m(\u001b[38;5;28mself\u001b[39m: T, dtype, copy: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m, errors: \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mraise\u001b[39m\u001b[38;5;124m\"\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m T:\n\u001b[1;32m--> 450\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mapply\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mastype\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdtype\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdtype\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcopy\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcopy\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43merrors\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43merrors\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\pandas\\core\\internals\\managers.py:352\u001b[0m, in \u001b[0;36mBaseBlockManager.apply\u001b[1;34m(self, f, align_keys, ignore_failures, **kwargs)\u001b[0m\n\u001b[0;32m 350\u001b[0m applied \u001b[38;5;241m=\u001b[39m b\u001b[38;5;241m.\u001b[39mapply(f, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 351\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 352\u001b[0m applied \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mgetattr\u001b[39m(b, f)(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 353\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (\u001b[38;5;167;01mTypeError\u001b[39;00m, \u001b[38;5;167;01mNotImplementedError\u001b[39;00m):\n\u001b[0;32m 354\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m ignore_failures:\n", - "File \u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\pandas\\core\\internals\\blocks.py:526\u001b[0m, in \u001b[0;36mBlock.astype\u001b[1;34m(self, dtype, copy, errors)\u001b[0m\n\u001b[0;32m 508\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 509\u001b[0m \u001b[38;5;124;03mCoerce to the new dtype.\u001b[39;00m\n\u001b[0;32m 510\u001b[0m \n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 522\u001b[0m \u001b[38;5;124;03mBlock\u001b[39;00m\n\u001b[0;32m 523\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 524\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mvalues\n\u001b[1;32m--> 526\u001b[0m new_values \u001b[38;5;241m=\u001b[39m \u001b[43mastype_array_safe\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvalues\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdtype\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcopy\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcopy\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43merrors\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43merrors\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 528\u001b[0m new_values \u001b[38;5;241m=\u001b[39m maybe_coerce_values(new_values)\n\u001b[0;32m 529\u001b[0m newb \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmake_block(new_values)\n", - "File \u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\pandas\\core\\dtypes\\astype.py:299\u001b[0m, in \u001b[0;36mastype_array_safe\u001b[1;34m(values, dtype, copy, errors)\u001b[0m\n\u001b[0;32m 296\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m values\u001b[38;5;241m.\u001b[39mcopy()\n\u001b[0;32m 298\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 299\u001b[0m new_values \u001b[38;5;241m=\u001b[39m \u001b[43mastype_array\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvalues\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdtype\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcopy\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcopy\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 300\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (\u001b[38;5;167;01mValueError\u001b[39;00m, \u001b[38;5;167;01mTypeError\u001b[39;00m):\n\u001b[0;32m 301\u001b[0m \u001b[38;5;66;03m# e.g. astype_nansafe can fail on object-dtype of strings\u001b[39;00m\n\u001b[0;32m 302\u001b[0m \u001b[38;5;66;03m# trying to convert to float\u001b[39;00m\n\u001b[0;32m 303\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m errors \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mignore\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n", - "File \u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\pandas\\core\\dtypes\\astype.py:230\u001b[0m, in \u001b[0;36mastype_array\u001b[1;34m(values, dtype, copy)\u001b[0m\n\u001b[0;32m 227\u001b[0m values \u001b[38;5;241m=\u001b[39m values\u001b[38;5;241m.\u001b[39mastype(dtype, copy\u001b[38;5;241m=\u001b[39mcopy)\n\u001b[0;32m 229\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 230\u001b[0m values \u001b[38;5;241m=\u001b[39m \u001b[43mastype_nansafe\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvalues\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdtype\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcopy\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcopy\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 232\u001b[0m \u001b[38;5;66;03m# in pandas we don't store numpy str dtypes, so convert to object\u001b[39;00m\n\u001b[0;32m 233\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(dtype, np\u001b[38;5;241m.\u001b[39mdtype) \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28missubclass\u001b[39m(values\u001b[38;5;241m.\u001b[39mdtype\u001b[38;5;241m.\u001b[39mtype, \u001b[38;5;28mstr\u001b[39m):\n", - "File \u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\pandas\\core\\dtypes\\astype.py:170\u001b[0m, in \u001b[0;36mastype_nansafe\u001b[1;34m(arr, dtype, copy, skipna)\u001b[0m\n\u001b[0;32m 166\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(msg)\n\u001b[0;32m 168\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m copy \u001b[38;5;129;01mor\u001b[39;00m is_object_dtype(arr\u001b[38;5;241m.\u001b[39mdtype) \u001b[38;5;129;01mor\u001b[39;00m is_object_dtype(dtype):\n\u001b[0;32m 169\u001b[0m \u001b[38;5;66;03m# Explicit copy, or required since NumPy can't view from / to object.\u001b[39;00m\n\u001b[1;32m--> 170\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43marr\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mastype\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdtype\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcopy\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[0;32m 172\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m arr\u001b[38;5;241m.\u001b[39mastype(dtype, copy\u001b[38;5;241m=\u001b[39mcopy)\n", - "\u001b[1;31mValueError\u001b[0m: could not convert string to float: '9 (0)'" - ] - } - ], + "outputs": [], "source": [ "from modelseedpy import MSCommScores, commscores_report\n", "import os\n", diff --git a/modelseedpy/community/commscores_template.html b/modelseedpy/community/commscores_template.html index 0d493b9f..cab8ea91 100644 --- a/modelseedpy/community/commscores_template.html +++ b/modelseedpy/community/commscores_template.html @@ -20,7 +20,6 @@ } } - @@ -43,92 +42,95 @@

CommScores Results

\ No newline at end of file diff --git a/modelseedpy/community/metquest_code.py b/modelseedpy/community/metquest_code.py new file mode 100644 index 00000000..e7cf27ca --- /dev/null +++ b/modelseedpy/community/metquest_code.py @@ -0,0 +1,1166 @@ +# -*- coding: utf-8 -*- + +from __future__ import absolute_import +from collections import deque, defaultdict +import os +import glob +import sys +import warnings +import itertools +import re +import pandas as pd +import numpy as np +import cobra +import networkx as nx + +warnings.filterwarnings("ignore") + + +def _create_graph_with_internal_reaction(organismsdata): + """ + This function creates a NetworkX DiGraph object which consists of + reactions and metabolites happening inside the organisms in a community. + This makes use of the reaction information i.e., irreversible and + reversible, which is obtained from another script fetch_reactions. + + Parameters + ---------- + organismsdata : dict + Dictionary containing the reaction information about organisms + + Returns + ------- + G : NetworkX DiGraph Object + Bipartite graph consisting of internal reactions in organisms + """ + G = nx.DiGraph() + for modelname in organismsdata: + G.add_nodes_from(organismsdata[modelname] + ['irreversible_rxn_no'], bipartite=1) + G.add_nodes_from(organismsdata[modelname] + ['reversible_rxn_no'], bipartite=1) + G.add_nodes_from(organismsdata[modelname] + ['reversible_back_rxn_no'], bipartite=1) + irrev_lhs_nodes = list(set( + [item for sublist in organismsdata[modelname]['irreversible_lhs_nodes'] + for item in sublist])) + irrev_rhs_nodes = list(set( + [item for sublist in organismsdata[modelname]['irreversible_rhs_nodes'] + for item in sublist])) + rev_lhs_nodes = list(set( + [item for sublist in organismsdata[modelname]['reversible_lhs_nodes'] + for item in sublist])) + rev_rhs_nodes = list(set( + [item for sublist in organismsdata[modelname]['reversible_rhs_nodes'] + for item in sublist])) + G.add_nodes_from(irrev_lhs_nodes, bipartite=0) + G.add_nodes_from(irrev_rhs_nodes, bipartite=0) + G.add_nodes_from(rev_lhs_nodes, bipartite=0) + G.add_nodes_from(rev_rhs_nodes, bipartite=0) + for irrevidx in range(len(organismsdata[modelname]['irreversible_rxn_no'])): + for lhsmetidx in range(len(organismsdata[modelname]['irreversible_lhs_nodes'][irrevidx])): + G.add_edges_from([(organismsdata[modelname]['irreversible_lhs_nodes'][irrevidx] + [lhsmetidx], + organismsdata[modelname]['irreversible_rxn_no'][irrevidx])]) + for rhsmetidx in range(len(organismsdata[modelname]['irreversible_rhs_nodes'][irrevidx])): + G.add_edges_from([(organismsdata[modelname]['irreversible_rxn_no'][irrevidx], + organismsdata[modelname]['irreversible_rhs_nodes'][irrevidx][rhsmetidx])]) + for revidx in range(len(organismsdata[modelname]['reversible_rxn_no'])): + for lhsmetidxrev in range(len(organismsdata[modelname]['reversible_lhs_nodes'][revidx])): + G.add_edges_from([(organismsdata[modelname]['reversible_lhs_nodes'][revidx] + [lhsmetidxrev], + organismsdata[modelname]['reversible_rxn_no'][revidx])]) + G.add_edges_from([(organismsdata[modelname]['reversible_back_rxn_no'][revidx], + organismsdata[modelname]['reversible_lhs_nodes'][revidx][lhsmetidxrev])]) + for rhsmetidxrev in range(len(organismsdata[modelname]['reversible_rhs_nodes'][revidx])): + G.add_edges_from([(organismsdata[modelname]['reversible_rxn_no'][revidx], + organismsdata[modelname]['reversible_rhs_nodes'][revidx][rhsmetidxrev])]) + G.add_edges_from([(organismsdata[modelname]['reversible_rhs_nodes'][revidx] + [rhsmetidxrev], + organismsdata[modelname]['reversible_back_rxn_no'][revidx])]) + return G + + +def _create_graph_with_exchange_reactions(G, orgs, namemap): + """ + This function first identifies the common exchange metabolites + and the non-common exchange metabolites and adds them to the + DiGraph object generated above. + + Parameters + ---------- + G : NetworkX DiGraph Object + Bipartite graph of reaction network from organisms + orgs : dict + Dictionary consisting of irreversible, reversible and exchange + reactions pertaining to the organisms. If more than one organism + is used, this dictionary consists of information about all the + organisms. + namemap : dict + Dictionary mapping the adhoc reaction names to reaction names in + the model + + Returns + ------- + G : NetworkX DiGraph Object + Bipartite graph consisting of internal and exchange reactions in organisms + namemap : dict + Dictionary mapping the adhoc exchange reaction names to reaction names in + the model + """ + metabolite_exchanged = [] + for orgnames in orgs: + exc_met = orgs[orgnames]['exchange_metab_nodes'] + metabolite_exchanged.append(exc_met) + # Common exchange metabolites in different organisms + common_exchange_metabolite = list( + set.intersection(*list(map(set, metabolite_exchanged)))) + common_exchange_metabolite.sort() + # Adding the common exchange metabolites to the graph + for orgnames in orgs: + renamed_exc_met = [orgnames + ' ' + + comexcmet for comexcmet in common_exchange_metabolite] + number_exc_met = list(range(0, len(common_exchange_metabolite))) + mod_exc_rxn_number = ['Org_%s ER' % + orgnames + str(num + 1) for num in number_exc_met] + mod_exc_rev_rxn_number = ['Org_%s ERR' % + orgnames + str(num + 1) for num in number_exc_met] + G.add_nodes_from(mod_exc_rxn_number, bipartite=1) + G.add_nodes_from(mod_exc_rev_rxn_number, bipartite=1) + G.add_nodes_from(common_exchange_metabolite, bipartite=0) + G.add_nodes_from(renamed_exc_met, bipartite=0) + for k in range(len(renamed_exc_met)): + namemap[mod_exc_rxn_number[k]] = common_exchange_metabolite[k] + namemap[mod_exc_rev_rxn_number[k]] = common_exchange_metabolite[k] + G.add_edges_from([(renamed_exc_met[k], mod_exc_rxn_number[k])]) + G.add_edges_from( + [(mod_exc_rxn_number[k], common_exchange_metabolite[k])]) + G.add_edges_from( + [(common_exchange_metabolite[k], mod_exc_rev_rxn_number[k])]) + G.add_edges_from([(mod_exc_rev_rxn_number[k], renamed_exc_met[k])]) + # Adding the non common exchange metabolites to the graph + for orgnames in orgs: + metitems = orgs[orgnames]['exchange_metab_nodes'] + non_common_exc_met = list( + set(metitems) - set(common_exchange_metabolite)) + non_common_exc_met.sort() + renamed_non_common_exc_met = [ + orgnames + ' ' + s for s in non_common_exc_met] + number_non_common_exc_met = list(range(0, len(non_common_exc_met))) + mod_non_common_exc_rxn_number = [ + 'Org_%s NCER' % orgnames + str(num + 1) for num in number_non_common_exc_met] + mod_non_common_exc_rev_rxn_number = [ + 'Org_%s NCERR' % orgnames + str(num + 1) for num in number_non_common_exc_met] + G.add_nodes_from(mod_non_common_exc_rxn_number, bipartite=1) + G.add_nodes_from(mod_non_common_exc_rev_rxn_number, bipartite=1) + G.add_nodes_from(non_common_exc_met, bipartite=0) + G.add_nodes_from(renamed_non_common_exc_met, bipartite=0) + for k in range(len(renamed_non_common_exc_met)): + namemap[mod_non_common_exc_rxn_number[k]] = non_common_exc_met[k] + namemap[mod_non_common_exc_rev_rxn_number[k] + ] = non_common_exc_met[k] + G.add_edges_from( + [(renamed_non_common_exc_met[k], mod_non_common_exc_rxn_number[k])]) + G.add_edges_from( + [(mod_non_common_exc_rxn_number[k], non_common_exc_met[k])]) + G.add_edges_from( + [(non_common_exc_met[k], mod_non_common_exc_rev_rxn_number[k])]) + G.add_edges_from( + [(mod_non_common_exc_rev_rxn_number[k], renamed_non_common_exc_met[k])]) + return G, namemap + + +def create_graph(file_names, no_of_orgs): + """ + This function creates bipartite graph of the organisms based on the + path provided and the number of organsisms. For instance, if a folder + has 3 model files, and the number of organisms is 2, 3 (3C2) different + bipartite graphs are created. The graph objects and the dictionary + are saved as gpickle and pickle files respectively. + + Parameters + ---------- + file_names : list + List containing the file names of models + no_of_orgs : int + Number of organisms to be used for creating the DiGraph. + + Returns + ------- + H : NetworkX DiGraph Object + Bipartite graph consisting of internal and exchange reactions in organisms + full_name_map : dict + Dictionary mapping the adhoc reaction names to reaction names in + the model + """ + + H=[] + organisms_reaction_data, partial_name_map = segregate_reactions_from_models(file_names) + if organisms_reaction_data: + organisms_names = list(organisms_reaction_data.keys()) + all_possible_combis = list(itertools.combinations( + list(range(len(organisms_names))), int(no_of_orgs))) + if int(no_of_orgs)>1 and sorted(organisms_names)[0][0]=='0': + all_possible_combis = all_possible_combis[:len(organisms_names)-1] + if all_possible_combis: + for ncom in range(len(all_possible_combis)): + file_name = '' + current_combination = {} + for numincom in range(len(all_possible_combis[ncom])): + current_combination[organisms_names[all_possible_combis[ncom][numincom]]] = \ + organisms_reaction_data[organisms_names[all_possible_combis[ncom][numincom]]] + file_name = file_name + \ + organisms_names[all_possible_combis[ncom] + [numincom]] + '_' + H.append(_create_graph_with_internal_reaction(current_combination)) + temp, full_name_map = _create_graph_with_exchange_reactions( + H[ncom], current_combination, partial_name_map) + H[ncom]=temp + print(len(H), H[ncom]) + print('Number of edges in graph', len(H[ncom].edges())) + print('Number of nodes in graph', len(H[ncom].nodes())) + + # Uncomment the following code to save the graph files externally in your machine + # Note: Graph files can occupy a large space for large datasets + ''' + if os.access(path_name_with_models, os.W_OK): + with open(file_name + 'namemap' + '.pickle', 'wb') as filetodump: + dump(full_name_map, filetodump) + nx.write_gpickle(H[ncom], file_name + '.gpickle') + print('Graph and namemap saved for file(s) in', path_name_with_models) + ''' + else: + print( + 'Number of organisms for creating a consortium graph is more than the models given') + print('Program will now exit') + sys.exit() + else: + print("Cannot create graph") + sys.exit() + return H, full_name_map + + +def forward_pass(graph_object, seedmets): + """ + This function carries out the Guided Breadth First Search on a directed + bipartite graph starting from the entries in seed metabolite set. + + Parameters + ---------- + graph_object : NetworkX DiGraph Object + Bipartite graph of the metabolic network + + seedmets : set + Set of seed metabolites including the source + + Returns + ------- + lower_bound_metabolite : defaultdict + Minimum number of steps required to reach a metabolite + status_dict : defaultdict + Dictionary pertaining to the status of every reaction - whether it + has been visited or not + scope : set + Set of metabolites that can be produced from the given set of + seed metabolites + + Notes + ----- + Starting with the set of seed metabolites S, the algorithm first finds + all the reactions from the set R, whose precursor metabolites are in S. + Such reactions are marked visited and added to the visited reaction set. + Metabolites produced by these reactions are checked. The reactions where + these metabolites participate are then checked for the presence of all its + predecessors and are added to the queue. This traversal continues in a + breadth-first manner and stops when there are no further reactions to + be visited. + """ + pred = graph_object.predecessors + succ = graph_object.successors + seed_metabolite_set = seedmets.copy() + lower_bound_metabolite = defaultdict(list) + lower_bound_reaction = defaultdict(list) + # Defaultdict is used simply because to avoid initialisations + status_dict = defaultdict(str) + # Using a deque since deques have O(1) speed for appendleft() and popleft() + # while lists have O(n) performance for inserting and popping. + queue = deque([]) + # All seed metabolites are always present, hence require 0 steps + for seedmetabs in seed_metabolite_set: + lower_bound_metabolite[seedmetabs].append(0) + stage = 1 + scope = seed_metabolite_set.copy() + starting_rxn_node = [] + # First stage where starting_rxn_node list contains all the reactions + # which require only the seed metabolites as input + for starting_met_nodes in seed_metabolite_set: + # Essential when analysing mutiple networks with same seed metabolite + # set, although would be redundant in case of single network + if starting_met_nodes in graph_object: + for startingrxns in succ(starting_met_nodes): + if set(pred(startingrxns)).issubset(seed_metabolite_set): + if startingrxns not in starting_rxn_node: + starting_rxn_node.append(startingrxns) + for metsprod in succ(startingrxns): + scope.add(metsprod) + if stage not in lower_bound_metabolite[metsprod]: + lower_bound_metabolite[metsprod].append(stage) + if stage not in lower_bound_reaction[startingrxns]: + lower_bound_reaction[startingrxns].append(stage) + for rxn in starting_rxn_node: + for metabs in succ(rxn): + for nextrxn in succ(metabs): + if set(pred(nextrxn)).issubset(scope): + if nextrxn not in queue: + queue.append(nextrxn) + status_dict[rxn] = 'V' + while queue: + stage += 1 + for parentrxn in list(queue): + if status_dict[parentrxn] == '': + if stage not in lower_bound_reaction[parentrxn]: + lower_bound_reaction[parentrxn].append(stage) + for mets in succ(parentrxn): + scope.add(mets) + if stage not in lower_bound_metabolite[mets]: + lower_bound_metabolite[mets].append(stage) + for progeny in succ(mets): + if set(pred(progeny)).issubset(scope): + + if status_dict[progeny] != 'V': + if progeny not in queue: + queue.append(progeny) + status_dict[parentrxn] = 'V' + elif status_dict[parentrxn] == 'V': + for mets in succ(parentrxn): + if stage not in lower_bound_metabolite[mets]: + lower_bound_metabolite[mets].append(stage) + queue.popleft() + return lower_bound_metabolite, status_dict, scope + +def find_different_reaction_types(stoi_matrix, model, current_model_name): + """ + This function finds the exchange, irreversible and the reversible reactions + from the model. + + Parameters + ---------- + stoi_matrix : numpy array + full path name where the model files are + model : COBRA model object + COBRA model object created from SBML models + current_model_name : str + Name which is to be prefixed against every + reaction/metabolite (to differentiate the entries in multiple organisms, + when a community model is built) + Returns + ------- + exchange_met_ids : list + Metabolite identifiers of exchange metabolites + irrev_lhs_nodes : list + Metabolite identifiers of reactants of irreversible reactions + irrev_rhs_nodes : list + Metabolite identifiers of products of irreversible reactions + rev_lhs_nodes : list + Metabolite identifiers of reactants of reversible reactions + rev_rhs_nodes : list + Metabolite identifiers of products of reversible reactions + exchange_rxn_ids : list + Reaction identifers of exchange reactions + irrev_rxn_ids : list + Reaction identifiers of irreversible reactions + rev_rxn_ids : list + Reaction identifiers of reversible reactions + + """ + + xdim = np.shape(stoi_matrix) + reactants_of_reaction = [] + total_metabolites_in_reaction = [] + products_of_reaction = [] + number_of_reactants_in_reaction = [] + total_number_of_metabs_in_reaction = [] + number_of_products_in_reaction = [] + exchange_reaction_idx = [] + reaction_identifiers = [] + reaction_in_model = [] + metabolite_identifiers = [] + for metab in model.metabolites: + metabolite_identifiers.append(metab.id) + for rxns in model.reactions: + reaction_identifiers.append(rxns.id) + reaction_in_model.append(rxns.reaction) + for rxnidx in range(xdim[0]): + reactants_of_reaction.append(np.where(stoi_matrix[rxnidx] == -1)) + total_metabolites_in_reaction.append(np.where(stoi_matrix[rxnidx] != 0)) + products_of_reaction.append(np.where(stoi_matrix[rxnidx] == 1)) + number_of_reactants_in_reaction.append(len(reactants_of_reaction[rxnidx][0])) + total_number_of_metabs_in_reaction.append(len(total_metabolites_in_reaction[rxnidx][0])) + number_of_products_in_reaction.append(len(products_of_reaction[rxnidx][0])) + + # Case 1 - Presence of bulk metabolites in the medium + + if reaction_in_model[rxnidx][-1] == 'b': # Assuming the bulk metabolites end in 'b' + if (number_of_reactants_in_reaction[rxnidx] == 1 and + number_of_products_in_reaction[rxnidx] == 1): + exchange_reaction_idx.append(rxnidx) + # Case 2 - Presence of exchange metabolites + elif (number_of_reactants_in_reaction[rxnidx] == 1 and + total_number_of_metabs_in_reaction[rxnidx] == 1): + exchange_reaction_idx.append(rxnidx) + elif (number_of_products_in_reaction[rxnidx] == 1 and + total_number_of_metabs_in_reaction[rxnidx] == 1): + exchange_reaction_idx.append(rxnidx) + exchange_met_ids = [] + exchange_met_index = [] + exchange_rxn_ids = [] + for excentry in exchange_reaction_idx: + exchange_rxn_ids.append(reaction_identifiers[excentry]) + if reaction_in_model[excentry][-1] == 'b': + exchange_met_ids.append(metabolite_identifiers + [np.nonzero(stoi_matrix[excentry])[0][0]]) + else: + exchange_met_index.append( + np.nonzero(stoi_matrix[excentry])[0].tolist()[0]) + if exchange_met_index: + for metind in exchange_met_index: + exchange_met_ids.append(metabolite_identifiers[metind]) + all_rxn_idx = list(range(len(reaction_in_model))) + internal_rxns = list(set(all_rxn_idx) ^ set(exchange_reaction_idx)) + reversible_rxns = [] + irreversible_rxns = [] + rxns_lowerbound = [] + rxns_upperbound = [] + for rxns in model.reactions: + rxns_lowerbound.append(rxns.lower_bound) + rxns_upperbound.append(rxns.upper_bound) + for idxint in internal_rxns: + if rxns_lowerbound[idxint] < 0 and rxns_upperbound[idxint] >= 0: + reversible_rxns.append(idxint) + elif rxns_lowerbound[idxint] >= 0 and rxns_upperbound[idxint] >= 0: + irreversible_rxns.append(idxint) + # Irreversible reaction nodes + irrev_lhs_temporary = [] + irrev_rhs_temporary = [] + irrev_lhs_nodes = [] + irrev_rhs_nodes = [] + irrev_rxn_ids = [] + for irridx in irreversible_rxns: + irrev_rxn_ids.append(reaction_identifiers[irridx]) + irrev_lhs_temporary.append(np.where(stoi_matrix[irridx] < 0)[0].tolist()) + irrev_rhs_temporary.append(np.where(stoi_matrix[irridx] > 0)[0].tolist()) + for lhsirridx in range(len(irrev_lhs_temporary)): + temp_metab_list_lhs = [] + for met_idx_lhs in irrev_lhs_temporary[lhsirridx]: + met_namech_lhs = "%s %s" % (current_model_name, + metabolite_identifiers[met_idx_lhs]) + temp_metab_list_lhs.append(met_namech_lhs) + irrev_lhs_nodes.append(temp_metab_list_lhs) + for rhsirridx in range(len(irrev_rhs_temporary)): + temp_metab_list_rhs = [] + for met_idx_rhs in irrev_rhs_temporary[rhsirridx]: + met_namech_rhs = "%s %s" % (current_model_name, + metabolite_identifiers[met_idx_rhs]) + temp_metab_list_rhs.append(met_namech_rhs) + irrev_rhs_nodes.append(temp_metab_list_rhs) + + # Reversible reaction nodes + rev_lhs_temporary = [] + rev_rhs_temporary = [] + rev_lhs_nodes = [] + rev_rhs_nodes = [] + rev_rxn_ids = [] + for rridx in reversible_rxns: + rev_rxn_ids.append(reaction_identifiers[rridx]) + rev_lhs_temporary.append(np.where(stoi_matrix[rridx] < 0)[0].tolist()) + rev_rhs_temporary.append(np.where(stoi_matrix[rridx] > 0)[0].tolist()) + for lhsrevidx in range(len(rev_lhs_temporary)): + temp_metab_list_lhs_rev = [] + for met_idx_lhs in rev_lhs_temporary[lhsrevidx]: + met_namech_lhs = "%s %s" % (current_model_name, + metabolite_identifiers[met_idx_lhs]) + temp_metab_list_lhs_rev.append(met_namech_lhs) + rev_lhs_nodes.append(temp_metab_list_lhs_rev) + for rhsrevidx in range(len(rev_rhs_temporary)): + temp_metab_list_rhs_rev = [] + for met_idx_rhs in rev_rhs_temporary[rhsrevidx]: + met_namech_rhs = "%s %s" % (current_model_name, + metabolite_identifiers[met_idx_rhs]) + temp_metab_list_rhs_rev.append(met_namech_rhs) + rev_rhs_nodes.append(temp_metab_list_rhs_rev) + return exchange_met_ids, irrev_lhs_nodes, \ + irrev_rhs_nodes, rev_lhs_nodes, rev_rhs_nodes, exchange_rxn_ids, \ + irrev_rxn_ids, rev_rxn_ids + + +def segregate_reactions_from_models(file_names): + """ + This function gets the data pertaining to the reactions and the + metabolites from the models of multiple organisms. + This requires as input the pathname where the '.xml' files are located. + From this path, this function reads all the files using the functions + in the COBRA toolbox and generates the stoichiometric model for these + SBML models. + + Parameters + ---------- + file_names : list + List of files names of models + + Returns + ------- + all_organisms_info : dict + Dictionary of all model data (reaction information about all the + organisms) + namemap : dict + Dictionary mapping the adhoc reaction names to reaction names in + the model + + """ + all_organisms_info = {} + namemap = {} + for model_names in file_names: + model = cobra.io.read_sbml_model(model_names) + stoi = cobra.util.array.create_stoichiometric_matrix(model) + if model.id: + current_model_name = model.id + else: + print("Model ID not found; using file name instead") + current_model_name = model_names.split('.')[0] + current_organisms_info = {current_model_name: {'exchange_metab_nodes': [], + 'irreversible_lhs_nodes': [], + 'irreversible_rhs_nodes': [], + 'reversible_rhs_nodes': [], + 'reversible_lhs_nodes': [], + 'irreversible_rxn_no': [], + 'reversible_rxn_no': [], + 'total_nodes': [], + 'model_rxns': [], + 'metabolites': [], + 'exch_rxn_name': [], + 'irrev_rxn_name': [], + 'rev_rxn_name': []}} + rxns_in_model = [] + mets_in_model = [] + for metab in model.metabolites: + mets_in_model.append(metab.id) + for reac in model.reactions: + rxns_in_model.append(reac.id) + stoi_matrix = stoi.T + exchange_nodes, irrev_lhs_nodes, irrev_rhs_nodes, rev_lhs_nodes, rev_rhs_nodes, \ + exc_name, irrev_rxn_name, rev_rxn_name = find_different_reaction_types( + stoi_matrix, model, current_model_name) + current_organisms_info[current_model_name][ + 'exchange_metab_nodes'] = exchange_nodes + current_organisms_info[current_model_name][ + 'irreversible_lhs_nodes'] = irrev_lhs_nodes + current_organisms_info[current_model_name][ + 'irreversible_rhs_nodes'] = irrev_rhs_nodes + current_organisms_info[current_model_name][ + 'reversible_lhs_nodes'] = rev_lhs_nodes + current_organisms_info[current_model_name][ + 'reversible_rhs_nodes'] = rev_rhs_nodes + current_organisms_info[current_model_name]['exch_rxn_name'] = exc_name + current_organisms_info[current_model_name][ + 'irrev_rxn_name'] = irrev_rxn_name + current_organisms_info[current_model_name][ + 'rev_rxn_name'] = rev_rxn_name + + irrev_rxn_number = [] + for num in range(len(irrev_lhs_nodes)): + modified_name_irrev = 'Org_%s IR' % current_model_name + str(num + 1) + irrev_rxn_number.append(modified_name_irrev) + namemap[modified_name_irrev] = irrev_rxn_name[num] + + rev_rxn_number = [] + for num in range(len(rev_lhs_nodes)): + modified_name_rev = 'Org_%s RR' % current_model_name + str(num + 1) + rev_rxn_number.append(modified_name_rev) + namemap[modified_name_rev] = rev_rxn_name[num] + + rev_back_rxn_number = [] + for num in range(len(rev_lhs_nodes)): + modified_name_back_rev = 'Org_%s RevBR' % current_model_name + \ + str(num + 1) + rev_back_rxn_number.append(modified_name_back_rev) + namemap[modified_name_back_rev] = rev_rxn_name[num] + + current_organisms_info[current_model_name][ + 'reversible_rxn_no'] = rev_rxn_number + current_organisms_info[current_model_name][ + 'irreversible_rxn_no'] = irrev_rxn_number + current_organisms_info[current_model_name]['total_nodes'] = len( + exchange_nodes) + len(irrev_lhs_nodes) + len(rev_lhs_nodes) + current_organisms_info[current_model_name]['model_rxns'] = rxns_in_model + current_organisms_info[current_model_name][ + 'reversible_back_rxn_no'] = rev_back_rxn_number + current_organisms_info[current_model_name]['metabolites'] = mets_in_model + all_organisms_info.update(current_organisms_info) + return all_organisms_info, namemap + +def get_models(file_names): + model = [] + for i in range(len(file_names)): + temp = cobra.io.read_sbml_model(file_names[i]) + if temp.id == '': + temp.id = file_names[i].split('.')[0] + model.append(temp) + + return model + + +def find_transport_rxns(file_names): + """ + This function finds all the transport and extracellular reactions in all models + :param file_names: list of GSMM file names + :return: + trans_rxn: list of transport and extracellular reactions in all models + """ + model = get_models(file_names) + exc_rxns = model[0].exchanges + met_id = list(exc_rxns[0].metabolites.keys())[0].id + pattern = re.compile(r'[_[][a-z]\d*[]]*') + exc_marker = pattern.findall(met_id) + trans_rxn = [] + for i in model: + for rxn in i.reactions: + for met in rxn.metabolites: + if met.id.find(exc_marker[-1]) >= 0: + trans_rxn.append(rxn.id) + return trans_rxn, model + +def find_relievedrxns(model, org_info, org_info_pert): + relieved = {} + detailed_rel_rxns = {} + rel_rxns_name = {} + for i in org_info_pert: + relieved[i] = list(set(org_info_pert[i]) - set(org_info[i])) + + for i in model: + j = i.id + detailed_rel_rxns[j] = [] + rel_rxns_name[j] = [] + if len(relieved[j]): + rxn_ids = [] + for r in i.reactions: + rxn_ids.append(r.id) + for rel in relieved[j]: + rel_rxn = i.reactions[rxn_ids.index(rel)].reaction + detailed_rel_rxns[j].append(rel_rxn) + rel_rxns_name[j].append(i.reactions[rxn_ids.index(rel)].name) + + return relieved, detailed_rel_rxns, rel_rxns_name + + +def preprocess_seedmets(seedmet_file, model): + f = open(seedmet_file, 'r') + seedmets, temp_seedmets = [], [] + while True: + l = f.readline().strip() + if l == '': break + temp_seedmets.append(l) + f.close() + + exc_rxns = model[0].exchanges + met_id = list(exc_rxns[0].metabolites.keys())[0].id + pattern = re.compile(r'[_[][a-z]\d*[]]*') + exc_marker = pattern.findall(met_id) + + for m in model: + for i in temp_seedmets: + seedmets.append(m.id + ' ' + i + exc_marker[0]) + seedmets.append(m.id + ' ' + i + exc_marker[0].replace('e', 'c')) + + return set(seedmets) + + +def find_stuckrxns(model, community, seedmet_file, no_of_orgs): + # Constructing graphs + + warnings.filterwarnings("ignore") + G, full_name_map = create_graph(community, no_of_orgs) + if not os.path.exists('results'): + os.makedirs('results') + f = open(seedmet_file, 'r') + + seedmets = preprocess_seedmets(seedmet_file, model) + + all_possible_combis = list(itertools.combinations(list(range(len(community))), int(no_of_orgs))) + if no_of_orgs > 1 and sorted(community)[0][0] == '0': + all_possible_combis = all_possible_combis[:len(community) - 1] + org_info = {} + scope = {} + print('No. of graphs constructed: ', len(G)) + + # This loop finds all the stuck reaction + + for i in range(len(all_possible_combis)): + lbm, sd, s = forward_pass(G[i], seedmets) + for j in range(len(all_possible_combis[i])): + stuck = [] + rxnNode = [] + model1 = model[all_possible_combis[i][j]].id + visited = list(sd.keys()) + for r in G[i].nodes: + if r.find(model1) >= 0: + rxnNode.append(r) + for rxn in rxnNode: + if rxn in visited: + continue + elif rxn.find('ERR') >= 0: + continue + elif rxn.find('Org') >= 0: + if (rxn[len(model1) + 5] == 'I') or (rxn[len(model1) + 5] == 'R'): + stuck.append(rxn) + org_info[model1] = stuck + scope[model1] = s + return org_info, scope, full_name_map + + +def decrypt_orginfo(org_info, namemap): + """ + This function decrypts the rxn ids using the data in corresponding namemaps + :param org_info: + :param namemap: + :return: + org_info: An dictionary of decrypted rxn ids for each community + """ + for i in org_info: + for j in range(len(org_info[i])): + org_info[i][j] = namemap[org_info[i][j]] + return org_info + + +def make_perturbed_community(rem_org, pert_models, pert_community): + pert_model_ids = [i.id for i in pert_models] + for i in rem_org: + if i in pert_model_ids: + pert_models.remove(pert_models[pert_model_ids.index(i)]) + pert_community.remove(pert_community[pert_model_ids.index(i)]) + pert_model_ids.remove(i) + + return pert_models, pert_community, pert_model_ids + + +def perform_task(cluster_file, sd_file, model, transport_rxns, pert_community, + org_info_wo_trans_rxn, rem_org_list, n): + org_info_pert, scope_pert, namemap_pert = \ + find_stuckrxns(model, pert_community, sd_file, len(pert_community)) + org_info_pert = decrypt_orginfo(org_info_pert, namemap_pert) + org_info_pert_wo_trans_rxn = {} + for i in org_info_pert: + org_info_pert_wo_trans_rxn[i] = list(set(org_info_pert[i]) - set(transport_rxns)) + + g = open('results/clusterKO_' + os.path.basename(cluster_file).replace('.csv', '') + '_' + + os.path.basename(sd_file).replace('.txt', '') + '/Community_without_clus' + str(n) + '.csv', 'w') + for m in org_info_pert_wo_trans_rxn: + g.write(m + ',' + str(len(org_info_pert_wo_trans_rxn[m])) + '\n') + g.close() + stuck_com = 0 + stuck_pert_com = 0 + for i in org_info_wo_trans_rxn: + if i not in rem_org_list: + stuck_com += len(org_info_wo_trans_rxn[i]) + for i in org_info_pert_wo_trans_rxn: + stuck_pert_com += len(org_info_pert_wo_trans_rxn[i]) + msi = 1 - (stuck_com / stuck_pert_com) + print(n, 'th cluster') + return org_info_pert, org_info_pert_wo_trans_rxn, msi + + +def write_relieved_rxns(g, relieved, detailed_rel_rxns, rel_rxns_name): + g.write('acceptor\trelieved reactions\n') + + for i in relieved: + g.write(i + '\t') + rel_rxns = list(set(relieved[i])) + det_rel_rxns = list(set(detailed_rel_rxns[i])) + rel_rxn_nam = list(set(rel_rxns_name[i])) + for j in rel_rxns: + g.write(j + '\t') + g.write('\n') + g.write('\t') + for d in rel_rxn_nam: + g.write(d + '\t') + g.write('\n') + g.write('\t') + for k in det_rel_rxns: + g.write(k + '\t') + g.write('\n') + + +def write_relieved_rxn_metadata(h, org_info_wo_trans_rxn, org_info_pert_wo_trans_rxn): + nrelieved = {} + for i in org_info_pert_wo_trans_rxn: + nrelieved[i] = len(org_info_pert_wo_trans_rxn[i]) - len(org_info_wo_trans_rxn[i]) + if nrelieved[i]: + h.write(i + ',' + str(len(org_info_wo_trans_rxn[i])) + ',' + str( + len(org_info_pert_wo_trans_rxn[i])) + ',' + str(nrelieved[i]) + '\n') + + +def find_relieved_rxn(model, seed_name, org_info_single, org_info_pair): + """ + This function extracts and writes the relieved rxns into a tsv file + :param model: + :param seed_name: name of the media used (identifer to know what media is used when analysis is done using multiple media) + :param org_info_single: Dictionary containing stuck reactions of all microbes in the community + :param org_info_pair: Dictionary containing stuck reactions of all microbes in the community + :return: None + """ + relieved = {} + for org1 in model: + for org2 in model: + if org1.id + '_' + org2.id in org_info_pair.keys(): + relieved[org1.id + '_' + org2.id] = [] + temp = list( + set(org_info_single[org1.id + '_' + org1.id]) - set(org_info_pair[org1.id + '_' + org2.id])) + for j in temp: + relieved[org1.id + '_' + org2.id].append(j) + else: + continue + + rel_rxns_name = {} + detailed_rel_rxns = {} + for i in model: + rxn_ids = [] + for r in i.reactions: + rxn_ids.append(r.id) + for j in model: + org1 = i.id + org2 = j.id + if org1 + '_' + org2 in relieved.keys(): + detailed_rel_rxns[org1 + '_' + org2] = [] + rel_rxns_name[org1 + '_' + org2] = [] + for rel in relieved[org1 + '_' + org2]: + rel_rxn = i.reactions[rxn_ids.index(rel)].reaction + detailed_rel_rxns[org1 + '_' + org2].append(rel_rxn) + rel_rxns_name[org1 + '_' + org2].append(i.reactions[rxn_ids.index(rel)].name) + + relieved_rxn_output_file = 'results/relieved_rxns_' + seed_name + '_w_excrxns.tsv' + with open(relieved_rxn_output_file, 'w') as g: + header = 'acceptor\tdonor\trelieved reactions\n' + g.write(header) + for i in model: + for j in model: + org1 = i.id + org2 = j.id + if org1 + '_' + org2 in relieved.keys(): + g.write(org1 + '\t' + org2 + '\t') + rel_rxns = list(set(relieved[org1 + '_' + org2])) + det_rel_rxns = list(set(detailed_rel_rxns[org1 + '_' + org2])) + rel_rxn_nam = list(set(rel_rxns_name[org1 + '_' + org2])) + for x in rel_rxns: + g.write(x + '\t') + g.write('\n') + g.write('\t' + '\t') + for d in rel_rxn_nam: + g.write(d + '\t') + g.write('\n') + g.write('\t' + '\t') + for k in det_rel_rxns: + g.write(k + '\t') + g.write('\n') + print('relieved reactions are written at:\n', relieved_rxn_output_file) + +def preprocess_seedmets(seedmet_file, model): + f = open(seedmet_file, 'r') + seedmets, temp_seedmets = [], [] + while True: + l = f.readline().strip() + if l == '': break + temp_seedmets.append(l) + f.close() + + exc_rxns = model[0].exchanges + met_id = list(exc_rxns[0].metabolites.keys())[0].id + pattern = re.compile(r'[_[][a-z]\d*[]]*') + exc_marker = pattern.findall(met_id) + + for m in model: + for i in temp_seedmets: + seedmets.append(m.id + ' ' + i + exc_marker[0]) + seedmets.append(m.id + ' ' + i + exc_marker[0].replace('e', 'c')) + + return set(seedmets) + +def find_stuck_rxns(model, community, seedmet_file, no_of_orgs): + """ + Constructs graphs using MetQuest and finds all stuck reactions in the cellular compartment + :param model: + :param community: list of GSMM files + :param seedmet_file: path to txt file containing seed metabolites + :param no_of_orgs: number of organisms in a community + :return: + org_info: Dictionary containing stuck reactions of all microbes in the community + scope: Dictionary containing all the metabolites that can be produced by the microbes in the community + namemap: Dictionaru containing all the decrypted rxn ids + """ + + warnings.filterwarnings("ignore") + G, full_name_map = create_graph(community, no_of_orgs) + if not os.path.exists('results'): + os.makedirs('results') + + seedmets = preprocess_seedmets(seedmet_file, model) + + all_possible_combis = list(itertools.combinations(list(range(len(community))), int(no_of_orgs))) + if no_of_orgs > 1 and sorted(community)[0][0] == '0': + all_possible_combis = all_possible_combis[:len(community) - 1] + org_info = {} + scope = {} + vis = {} + print('No. of graphs constructed: ', len(G)) + + # This loop finds all the stuck reaction + + for i in range(len(all_possible_combis)): + lbm, sd, s = forward_pass(G[i], seedmets) + for j in range(len(all_possible_combis[i])): + stuck = [] + rxnNode = [] + model1 = model[all_possible_combis[i][j]].id + visited = list(sd.keys()) + for r in G[i].nodes: + if r.find(model1) >= 0: + rxnNode.append(r) + for rxn in rxnNode: + if rxn in visited: + continue + elif rxn.find('ERR') >= 0: + continue + elif rxn.find('Org') >= 0: + if (rxn[len(model1) + 5] == 'I') or (rxn[len(model1) + 5] == 'R'): + stuck.append(rxn) + model2 = model[all_possible_combis[i][j - 1]].id + org_info[model1 + '_' + model2] = stuck + scope[model1 + '_' + model2] = s + vis[model1 + '_' + model2] = visited + return org_info, scope, full_name_map, vis + +def decrypt_org_info(org_info, namemap): + """ + This function decrypts the rxn ids using the data in corresponding namemaps + :param org_info: + :param namemap: + :return: + org_info: An dictionary of decrypted rxn ids for each community + """ + for i in org_info: + for j in range(len(org_info[i])): + org_info[i][j] = namemap[org_info[i][j]] + return org_info + +def pMSI(community, sd_file): + """ + Calculates MSI for CarveMe models + Extracts and writes relieved reactions in every pair + :param community: list of GSMM files + :param sd_file: path to txt file containing seed metabolites + :return: msi: Dictionary containing MSI values for every pair + """ + # find all transport reactions + transport_rxns, model = find_transport_rxns(community) + # find stuck reactions + org_info_single, scope_sin, namemap_sin, vis = find_stuck_rxns(model, community, sd_file, 1) + community = glob.glob('*.xml') + if not community: + community = glob.glob('*.sbml') + community.sort() + org_info_pair, scope_pair, namemap_pair, vis = find_stuck_rxns(model, community, sd_file, 2) + # decrypt the stuck reactions + org_info_single = decrypt_org_info(org_info_single, namemap_sin) + org_info_pair = decrypt_org_info(org_info_pair, namemap_pair) + # Filter out the transport reactions from every stuck reaction list + org_info_single_wo_trans_rxn, org_info_pair_wo_trans_rxn = {}, {} + for i in org_info_single: + org_info_single_wo_trans_rxn[i] = list(set(org_info_single[i]) - set(transport_rxns)) + for i in org_info_pair: + org_info_pair_wo_trans_rxn[i] = list(set(org_info_pair[i]) - set(transport_rxns)) + # find all the relieved reactions in every pairs + find_relieved_rxn(model, os.path.basename(sd_file).replace('.txt', ''), org_info_single, + org_info_pair) + # calculate MSI for every pair + msi = {} + for org1 in model: + stuck_A = len(org_info_single_wo_trans_rxn[org1.id + '_' + org1.id]) + for org2 in model: + if org1.id + '_' + org2.id in org_info_pair_wo_trans_rxn.keys(): + stuck_AUB = len(org_info_pair_wo_trans_rxn[org1.id + '_' + org2.id]) + if stuck_A == 0: + msi[org1.id + '_' + org2.id] = 0 + else: + msi[org1.id + '_' + org2.id] = 1 - (stuck_AUB / stuck_A) + return msi, model + +def calculate_pairwiseMSI(path, sd_file): + """ + This function calculates pairwise-MSI for all given microbes. + + Creates a csv file containing the MSI values of all pairs. + + Creates an tsv file containing the list of reaction relieved + in all acceptor microbes in the presence of corresponding donor microbes. + + :param path: path to all xml files + :param sd_file: path to txt file containing seed metabolites + """ + + warnings.filterwarnings("ignore") + os.chdir(path) + file_names = glob.glob('*.xml') + if not file_names: + file_names = glob.glob('*.sbml') + + if not file_names: + print("There are no sbml files. Please check the path") + return + print("Filenames", file_names) + sys.path.append(path) + community = file_names.copy() + community.sort() + + msi, model = pMSI(community, sd_file) + + msi_output_file = 'results/MSI_' + os.path.basename(sd_file).replace('.txt', '') + '.csv' + with open(msi_output_file, 'w') as f: + header = 'organism,in_the_presence,msi_value\n' + f.write(header) + for org1 in model: + for org2 in model: + if org1.id + '_' + org2.id in msi.keys(): + f.write(org1.id + ',' + org2.id + ',' + str(msi[org1.id + '_' + org2.id]) + '\n') + print('MSI values are written at:\n', msi_output_file) + + def calculate_higherorderMSI(path, sd_file, cluster_file): + os.chdir(path) + file_names = glob.glob('*.xml') + if not file_names: + file_names = glob.glob('*.sbml') + + if not file_names: + print("There are no .xml files. Please check the path") + print("Filenames", file_names) + sys.path.append(path) + community = file_names + community.sort() + transport_rxns, model = find_transport_rxns(community) + org_info, scope, namemap = find_stuckrxns(model, community, sd_file, len(community)) + org_info = decrypt_orginfo(org_info, namemap) + org_info_wo_trans_rxn = {} + for i in org_info: + org_info_wo_trans_rxn[i] = list(set(org_info[i]) - set(transport_rxns)) + + if not os.path.exists('results/clusterKO_' + os.path.basename(cluster_file).replace('.csv', '') + + '_' + os.path.basename(sd_file).replace('.txt', '') + '/data_analysis'): + os.makedirs('results/clusterKO_' + os.path.basename(cluster_file).replace('.csv', '') + '_' + + os.path.basename(sd_file).replace('.txt', '') + '/data_analysis') + f = open('results/clusterKO_' + os.path.basename(cluster_file).replace('.csv', '') + '_' + + os.path.basename(sd_file).replace('.txt', '') + '/community_unperturbed.csv', 'w') + for i in org_info_wo_trans_rxn: + f.write(i + ',' + str(len(org_info_wo_trans_rxn[i])) + '\n') + f.close() + + if cluster_file == 'individual_clusters': + # file_names = glob.glob('*.xml') + # if not file_names: + # file_names = glob.glob('*.sbml') + rem_org_list1 = {} + rem_org_list2 = {} + + for i in range(len(model)): + rem_org_list1[i] = [model[i].id] + rem_org_list2[i] = [model[i].id] + + else: + cluster_data = pd.read_csv(cluster_file, sep=',') + rem_org_list1 = cluster_data.set_index('Cluster').T.to_dict('list') + for n in rem_org_list1: + rem_org_list1[n] = [j for j in rem_org_list1[n] if pd.isna(j) is False] + # model_ids = [i.id for i in model] + for n in rem_org_list1: + rem_org_list1[n] = [cobra.io.read_sbml_model(i).id for i in rem_org_list1[n]] + # rem_org_list1[n] = [model_ids[model_ids.index(i)] for i in rem_org_list1[n]] + + rem_org_list2 = rem_org_list1.copy() + + for nclus in rem_org_list2: + rem_org_list2[nclus] = [x.replace('.xml', '') for x in rem_org_list2[nclus]] + + f = open('results/clusterKO_' + os.path.basename(cluster_file).replace('.csv', '') + '_' + + os.path.basename(sd_file).replace('.txt', '') + '/higher_order_msi.csv', 'w') + for n in rem_org_list1: + os.chdir(path) + new_models = model.copy() + new_community = glob.glob('*.xml') + if not new_community: + new_community = glob.glob('*.sbml') + new_community.sort() + + pert_models, pert_community, pert_model_ids = make_perturbed_community(rem_org_list1[n], new_models, + new_community) + + org_info_pert, org_info_pert_wo_trans_rxn, msi = perform_task(cluster_file, sd_file, pert_models, + transport_rxns, + pert_community, org_info_wo_trans_rxn, + rem_org_list2[n], n) + for i in rem_org_list2[n]: + f.write('Comm,clus_' + str(n) + '#' + i + ',' + str(msi) + '\n') + + if msi: + relieved, detailed_rel_rxns, rel_rxns_name = find_relievedrxns(pert_models, org_info, org_info_pert) + g = open('results/clusterKO_' + os.path.basename(cluster_file).replace('.csv', '') + + '_' + os.path.basename(sd_file).replace('.txt', '') + + '/data_analysis/relieved_rxns_Comm--clus' + str(n) + '.tsv', 'w') + write_relieved_rxns(g, relieved, detailed_rel_rxns, rel_rxns_name) + g.close() + + h = open('results/clusterKO_' + os.path.basename(cluster_file).replace('.csv', '') + '_' + + os.path.basename(sd_file).replace('.txt', '') + '/data_analysis/Comm--clus' + str(n) + '.csv', + 'w') + h.write('Comm--clus' + str(n) + '\n') + for i in rem_org_list2[n]: + h.write(i + '\n') + h.write('num of rxns relieved in the below orgs in the presence of clust' + str(n) + '\n') + h.write('org,unpert,clust_' + str(n) + 'KO,rxns relieved\n') + write_relieved_rxn_metadata(h, org_info_wo_trans_rxn, org_info_pert_wo_trans_rxn) + h.close() + print('Comm--clus' + str(n)) + + os.chdir(path) + new_models = model.copy() + new_community = glob.glob('*.xml') + if not new_community: + new_community = glob.glob('*.sbml') + new_community.sort() + ko_models, ko_community, model_ids = make_perturbed_community(pert_model_ids, new_models, new_community) + ko_org_list = [x for x in pert_model_ids] + if len(ko_org_list) < len(model): + org_info_pert, org_info_pert_wo_trans_rxn, msi = perform_task(cluster_file, sd_file, ko_models, + transport_rxns, ko_community, + org_info_wo_trans_rxn, ko_org_list, n) + for i in ko_community: + f.write('clus_' + str(n) + '#' + i + ',Comm,' + str(msi) + '\n') + + if msi: + relieved, detailed_rel_rxns, rel_rxns_name = find_relievedrxns(ko_models, org_info, org_info_pert) + g = open('results/clusterKO_' + os.path.basename(cluster_file).replace('.csv', '') + + '_' + os.path.basename(sd_file).replace('.txt', '') + + '/data_analysis/relieved_rxns_clus--Comm' + str(n) + '.tsv', 'w') + write_relieved_rxns(g, relieved, detailed_rel_rxns, rel_rxns_name) + g.close() + + h = open('results/clusterKO_' + os.path.basename(cluster_file).replace('.csv', '') + '_' + + os.path.basename(sd_file).replace('.txt', '') + '/data_analysis/clus' + str( + n) + '--Comm.csv', + 'w') + h.write('clus' + str(n) + '--Comm\n') + for i in ko_org_list: + h.write(i + '\n') + h.write('num of rxns relieved in the below orgs in the presence of Comm') + h.write('org,unpert,commKO,rxns relieved\n') + write_relieved_rxn_metadata(h, org_info_wo_trans_rxn, org_info_pert_wo_trans_rxn) + h.close() + print('clus' + str(n) + '--Comm') + + f.close() + diff --git a/modelseedpy/community/mscommscores.py b/modelseedpy/community/mscommscores.py index 222f5e95..b274953d 100644 --- a/modelseedpy/community/mscommscores.py +++ b/modelseedpy/community/mscommscores.py @@ -320,9 +320,9 @@ def calculate_scores(pairs, models_media=None, environments=None, RAST_genomes=N if print_progress: print("GYD done\t\t", end="\t" if RAST_genomes else "\n") # determine the RAST Functional Complementarity content if kbase_obj is not None and RAST_genomes: - kbase_dic.update({"RFC": f"""{list(MSCommScores.rfc( + kbase_dic.update({"FC": f"""{list(MSCommScores.rfc( grouping, kbase_obj, RAST_genomes=RAST_genomes).values())[0]:.5f}"""}) - if print_progress: print("RFC done\t\t") + if print_progress: print("FC done\t\t") # return a pandas Series, which can be easily aggregated with other results into a DataFrame series.append(Series(kbase_dic)) count += 1