Commit message:
planemo upload for repository https://github.com/AlmaasLab/elixir-galaxy-tools-systemsbiology commit 3f7bec1264a86e1488ee1315dbac0f44675f5171 |
added:
gem_escher_visualization.py gem_escher_visualization.xml gem_extract_exchange.py gem_flux_distribution.py gem_flux_variability_analysis.py gem_knockout.py gem_macros.xml gem_phenotype_phase_plane.py test-data/e_coli_core_test_map.json test-data/expected_single_knockout.csv test-data/invalid_format.txt test-data/textbook_model_cobrapy.xml test-data/textbook_model_cobrapy_exchange.csv |
b |
diff -r 000000000000 -r b79cf44068bc gem_escher_visualization.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gem_escher_visualization.py Fri Dec 13 21:32:58 2024 +0000 |
[ |
@@ -0,0 +1,233 @@ +import argparse + +import cobra +import pandas as pd +from escher import Builder + + +def __main__(): + parser = argparse.ArgumentParser( + prog="EscherVisualization", + description="This program visualizes an Escher map", + epilog="Adding an epilog, but doubt it's needed.", + ) + parser.add_argument( + "-m", + "--cb_model_location", + dest="cb_model_location", + action="store", + type=str, + default=None, + required=False, + help="The model to use." + ) + parser.add_argument( + "-f", + "--flux_distribution_location", + dest="flux_distribution_location", + action="store", + type=str, + default=None, + required=False, + help="The flux distribution to visualize." + ) + parser.add_argument( + "-e", + "--expect_map", + dest="expect_map", + action="store", + type=str, + default=None, + required=True, + help="Is a map expected to be uploaded?" + ) + parser.add_argument( + "-l", + "--model_to_download", + dest="model_to_download", + action="store", + type=str, + default=None, + required=False, + help="The model to download." + ) + parser.add_argument( + "--map_load_name", + dest="map_load_name", + action="store", + type=str, + default=None, + required=False, + help="The name of the map to use." + ) + parser.add_argument( + "--map_upload_name", + dest="map_upload_name", + action="store", + type=str, + default=None, + required=False, + help="The name of the map to use." + ) + parser.add_argument( + "-u", + "--uptake_constraints_file", + dest="uptake_constraints_file", + action="store", + type=str, + default=None, + required=False, + help="File containing new uptake constraits." + ) + parser.add_argument( + "-output", + "--output", + dest="out_file", + action="store", + type=str, + default=None, + required=True, + help="The output file." + ) + + args = parser.parse_args() + + if args.expect_map not in ["True", "False"]: + raise Exception("The expect_map argument must be either True or False.") + if args.expect_map == "True" and args.map_load_name is None and \ + args.map_upload_name is None: + raise Exception( + "You must specify a map name if a map is expected to be uploaded." + ) + + cb_model = None + model_name = None + if args.model_to_download is not None and args.model_to_download != "None": + if args.cb_model_location is not None \ + and args.cb_model_location != "None": + raise Exception( + "You cannot specify both a model to " + "download and a model to use." + ) + model_name = args.model_to_download + elif args.cb_model_location is not None\ + and args.cb_model_location != "None": + try: + cb_model = cobra.io.read_sbml_model(args.cb_model_location) + except Exception as e: + raise Exception( + "The model could not be read. " + "Ensure it is in correct SBML format." + ) from e + + map_name = None + map_location = None + if args.map_upload_name is not None and args.map_upload_name != "None": + if args.map_load_name is not None and args.map_load_name != "None": + raise Exception( + "You cannot specify both a map to upload and a map to load." + ) + map_location = args.map_upload_name + elif args.map_load_name is not None and args.map_load_name != "None": + map_name = args.map_load_name + + if args.uptake_constraints_file is not None and \ + args.uptake_constraints_file != "None": + if cb_model is None: + raise Exception( + "You cannot specify uptake constraints " + "without uploading a model." + ) + else: + constraints_df = pd.read_csv( + args.uptake_constraints_file, + sep=";", + header=0, + index_col=False + ) + for index, row in constraints_df.iterrows(): + rxn_id = row["reaction_id"] + cb_model.reactions.get_by_id(rxn_id).lower_bound = \ + row["lower_bound"] + cb_model.reactions.get_by_id(rxn_id).upper_bound = \ + row["upper_bound"] + + flux_dict = None + if args.flux_distribution_location is not None and \ + args.flux_distribution_location != "None": + if cb_model is None: + raise Exception( + "You cannot specify a flux distribution " + "without uploading a model." + ) + if args.uptake_constraints_file is not None and \ + args.uptake_constraints_file != "None": + raise Exception( + "You cannot specify both uptake constraints and a flux " + "distribution." + ) + try: + flux_df = pd.read_csv( + args.flux_distribution_location, + sep=";", + header=0, + index_col=False + ) + flux_dict = { + key: value for key, value in zip( + flux_df['reaction_name'], + flux_df['flux'] + ) + } + except Exception as e: + raise Exception( + "The flux distribution file could not be read. " + "Ensure the file has semicolon-separated " + "columns and a header row." + ) from e + + if cb_model is not None and flux_dict is None: + solution = cobra.flux_analysis.pfba(cb_model) + + # make a dataframe with the reaction names, reaction ids, and flux + flux_distribution = pd.DataFrame( + columns=["reaction_name", "reaction_id", "flux"] + ) + flux_distribution["reaction_name"] = [ + reaction.name for reaction in cb_model.reactions + ] + flux_distribution["reaction_id"] = [ + reaction.id for reaction in cb_model.reactions + ] + flux_distribution["flux"] = [ + solution.fluxes[reaction.id] for reaction in cb_model.reactions + ] + flux_dict = { + key: value for key, value in zip( + flux_distribution['reaction_name'], + flux_distribution['flux'] + ) + } + + builder = Builder() + if map_name is not None: + builder.map_name = map_name + print("Downloading map...") + if map_location is not None: + builder.map_json = map_location + print("Uploading map...") + if model_name is not None: + builder.model_name = model_name + print("Downloading model...") + if cb_model is not None: + builder.model = cb_model + print("Uploading model...") + + if flux_dict is not None: + builder.reaction_data = flux_dict + + builder.save_html(args.out_file) + + +if __name__ == "__main__": + __main__() |
b |
diff -r 000000000000 -r b79cf44068bc gem_escher_visualization.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gem_escher_visualization.xml Fri Dec 13 21:32:58 2024 +0000 |
[ |
@@ -0,0 +1,154 @@ +<tool id="gem_escher_visualization" name="Pathway visualization" version="@VERSION@" profile="@PROFILE@"> + <description> + of a GEM using Escher + </description> + <macros> + <import>gem_macros.xml</import> + </macros> + <expand macro="requirements"/> + <expand macro="version_command_escher"/> + <command> + python '$__tool_directory__/gem_escher_visualization.py' + -output '${output}' + --cb_model_location '${cb_model_location}' + #if not $flux_distribution_location == "None": + --flux_distribution_location '${flux_distribution_location}' + #end if + #if not $uptake_constraints_file == "None": + --uptake_constraints_file '${uptake_constraints_file}' + #end if + #if $map_selection.map_selection_select == "upload_map" or $map_selection.map_selection_select == "load_map": + --expect_map 'True' + #elif $map_selection.map_selection_select == "no_map": + --expect_map 'False' + #end if + #if $map_selection.map_selection_select == "upload_map": + --map_upload_name '${map_selection.map_upload_name}' + #elif $map_selection.map_selection_select == "load_map": + --map_load_name '${map_selection.map_load_name}' + #end if + </command> + <inputs> + <expand macro="input_model"/> + <param format="tabular,csv" name="flux_distribution_location" type="data" label="Flux distribution to visualize flux for" optional="true"/> + <expand macro="input_uptake_constraints"/> + <conditional name="map_selection"> + <param format="select" name="map_selection_select" type="select" label="How would you like to select a map?"> + <option value="load_map">Load a map from the list below</option> + <option value="upload_map">Upload a map</option> + <option value="no_map">Don't use a map (I'll draw my own from scratch)</option> + </param> + <when value="load_map"> + <param format="select" name="map_load_name" type="select" label="Map to load" optional="false"> + <option value="iMM904.Central carbon metabolism">iMM904 (S. cerevisiae), Central carbon metabolism</option> + <option value="RECON1.Inositol retinol metabolism">RECON1 (H. sapiens), Inositol retinol metabolism</option> + <option value="RECON1.Glycolysis TCA PPP">RECON1 (H. sapiens), Glycolysis TCA PPP</option> + <option value="RECON1.Tryptophan metabolism">RECON1 (H. sapiens), Tryptophan metabolism</option> + <option value="RECON1.Carbohydrate metabolism">RECON1 (H. sapiens), Carbohydrate metabolism</option> + <option value="RECON1.Amino acid metabolism (partial)">RECON1 (H. sapiens), Amino acid metabolism (partial)</option> + <option value="iJO1366.Nucleotide metabolism">iJO1366 (E. coli), Nucleotide metabolism</option> + <option value="iJO1366.Fatty acid biosynthesis (saturated)">iJO1366 (E. coli), Fatty acid biosynthesis (saturated)</option> + <option value="iJO1366.Nucleotide and histidine biosynthesis">iJO1366 (E. coli), Nucleotide and histidine biosynthesis</option> + <option value="e_coli_core.Core metabolism">e_coli_core, Core metabolism</option> + <option value="iJO1366.Central metabolism">iJO1366 (E. coli), Central metabolism</option> + <option value="iJO1366.Fatty acid beta-oxidation">iJO1366 (E. coli), Fatty acid beta-oxidation</option> + </param> + </when> + <when value="upload_map"> + <param format="txt" name="map_upload_name" type="data" label="Map to use for visualizing fluxes" optional="true"/> + </when> + <when value="no_map"> + <!-- Do nothing --> + </when> + </conditional> + </inputs> + <outputs> + <data name="output" format="html" label="${tool.name} on ${on_string}"/> + </outputs> + <tests> + <!-- Test 1: Valid E. coli core model, no map --> + <test> + <param name="cb_model_location" value="textbook_model_cobrapy.xml"/> + <conditional name="map_selection"> + <param name="map_selection_select" value="no_map"/> + </conditional> + <output name="output"> + <assert_contents> + <has_line line=" var data = get_data();"/> + </assert_contents> + </output> + </test> + <!-- Test 2: Valid E. coli core model, load map --> + <test> + <param name="cb_model_location" value="textbook_model_cobrapy.xml"/> + <conditional name="map_selection"> + <param name="map_selection_select" value="load_map"/> + <param name="map_load_name" value="e_coli_core.Core metabolism"/> + </conditional> + <output name="output"> + <assert_contents> + <has_line line=" var data = get_data();"/> + </assert_contents> + </output> + </test> + <!-- Test 3: Valid E. coli core model, upload map --> + <test> + <param name="cb_model_location" value="textbook_model_cobrapy.xml"/> + <conditional name="map_selection"> + <param name="map_selection_select" value="upload_map"/> + <param name="map_upload_name" value="e_coli_core_test_map.json"/> + </conditional> + <output name="output"> + <assert_contents> + <has_line line=" var data = get_data();"/> + </assert_contents> + </output> + </test> + <!-- Test 4: Invalid model, no map --> + <test expect_failure="true"> + <param name="cb_model_location" value="invalid_format.txt"/> + <conditional name="map_selection"> + <param name="map_selection_select" value="no_map"/> + </conditional> + <assert_stderr> + <has_text text="The model could not be read"/> + </assert_stderr> + </test> + </tests> + <help><![CDATA[ + Escher Visualization Tool + + Overview + + This tool generates an interactive HTML visualization of metabolic flux distributions in a Genome-scale Metabolic Model (GEM) using Escher. + + Inputs + + * Model File (Required): COBRA-compatible metabolic model file + * Flux Distribution (Optional): a pre-calculated flux distribution + * Model constraints (Optional): constraints to apply during model simulation if no flux distribution is provided + * Map Selection (Optional): maps for common metabolic models + + Output + + The tool generates an interactive HTML file that: + * Displays metabolic pathways with reaction fluxes + * Allows zooming and panning + * Enables hovering over reactions for detailed information + * Provides options for customizing the visualization + + Tips + + * Ensure your model is properly formatted and constrained + * For large models, consider visualizing specific subsystems + * Custom maps should follow Escher's JSON format + * The visualization works best with modern web browsers + + For more information about Escher, visit: https://escher.github.io/ + ]]></help> + <citations> + <expand macro="citation_escher"/> + <expand macro="citation_pandas"/> + <expand macro="citation_cobrapy"/> + </citations> +</tool> |
b |
diff -r 000000000000 -r b79cf44068bc gem_extract_exchange.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gem_extract_exchange.py Fri Dec 13 21:32:58 2024 +0000 |
[ |
@@ -0,0 +1,80 @@ +import argparse + +import cobra + + +def read_model(model_location): + model = cobra.io.read_sbml_model(model_location) + return model + + +def get_exchange_reactions_info(model): + exchange_reactions = model.exchanges + exchange_reactions_info = [] + for reaction in exchange_reactions: + exchange_reactions_info.append( + [ + reaction.id, + reaction.name, + reaction.reaction, + reaction.lower_bound, + reaction.upper_bound + ]) + txt_object = ( + "reaction_id;reaction_name;reaction_stoichiometry;" + "lower_bound;upper_bound\n" + ) + for reaction in exchange_reactions_info: + txt_object += ";".join([str(x) for x in reaction]) + "\n" + return txt_object + + +def __main__(): + + # Parsing arguments + parser = argparse.ArgumentParser( + prog="GEM ", + description="This program retrieves the exchange fluxes " + "of a GEM model to be used in Galaxy.", + epilog="Adding an epilog, but doubt it's needed.", + ) + parser.add_argument( + "-m", + "--cb_model_location", + dest="cb_model_location", + action="store", + type=str, + default=None, + required=True, + help="The model to use." + ) + parser.add_argument( + "-output", + "--output", + dest="out_file", + action="store", + type=str, + default=None, + required=True, + help="The output file." + ) + args = parser.parse_args() + + # Reading model from file + try: + cb_model = read_model(args.cb_model_location) + except Exception as e: + raise Exception( + "The model could not be read. Ensure it is in correct SBML format." + ) from e + + # Getting exchange reactions info + answer = get_exchange_reactions_info(cb_model) + + # Writing exchange reactions info to file + with open(args.out_file, "w") as outfile: + outfile.write(str(answer)) + + +if __name__ == "__main__": + __main__() |
b |
diff -r 000000000000 -r b79cf44068bc gem_flux_distribution.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gem_flux_distribution.py Fri Dec 13 21:32:58 2024 +0000 |
[ |
@@ -0,0 +1,90 @@ +import argparse + +import cobra +import pandas as pd + + +def __main__(): + parser = argparse.ArgumentParser( + prog="FluxDistribution", + description="This program calculates the flux distribution of a GEM", + epilog="Adding an epilog, but doubt it's needed.", + ) + parser.add_argument( + "-m", + "--cb_model_location", + dest="cb_model_location", + action="store", + type=str, + default=None, + required=True, + help="The model to use." + ) + parser.add_argument( + "-output", + "--output", + dest="out_file", + action="store", + type=str, + default=None, + required=True, + help="The output file." + ) + parser.add_argument( + "-u", + "--uptake_constraints_file", + dest="uptake_constraints_file", + action="store", + type=str, + default=None, + required=False, + help="File containing new uptake constraits." + ) + + args = parser.parse_args() + + try: + cb_model = cobra.io.read_sbml_model(args.cb_model_location) + except Exception as e: + raise Exception( + "The model could not be read. Ensure " + "it is in correct SBML format." + ) from e + + if args.uptake_constraints_file is not None\ + and args.uptake_constraints_file != "None": + constraints_df = pd.read_csv( + args.uptake_constraints_file, + sep=";", + header=0, + index_col=False + ) + for _, row in constraints_df.iterrows(): + cb_model.reactions.get_by_id( + row["reaction_id"] + ).lower_bound = row["lower_bound"] + cb_model.reactions.get_by_id( + row["reaction_id"] + ).upper_bound = row["upper_bound"] + + # do pFBA + solution = cobra.flux_analysis.pfba(cb_model) + + # make a dataframe with the reaction names, + # reaction ids, and flux distribution + flux_distribution = pd.DataFrame( + columns=["reaction_name", "reaction_id", "flux"] + ) + + flux_distribution["reaction_name"] = \ + [reaction.name for reaction in cb_model.reactions] + flux_distribution["reaction_id"] = \ + [reaction.id for reaction in cb_model.reactions] + flux_distribution["flux"] = \ + [solution.fluxes[reaction.id] for reaction in cb_model.reactions] + + flux_distribution.to_csv(args.out_file, sep=";", index=False) + + +if __name__ == "__main__": + __main__() |
b |
diff -r 000000000000 -r b79cf44068bc gem_flux_variability_analysis.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gem_flux_variability_analysis.py Fri Dec 13 21:32:58 2024 +0000 |
[ |
@@ -0,0 +1,121 @@ +import argparse + +import cobra +import pandas as pd + + +def __main__(): + parser = argparse.ArgumentParser( + prog="FluxVariabilityAnalysis", + description="This program performs flux variability " + "analysis on a GEM", + epilog="Adding an epilog, but doubt it's needed.", + ) + parser.add_argument( + "-m", "--cb_model_location", + dest="cb_model_location", + action="store", + type=str, + default=None, + required=True, + help="The model to use." + ) + parser.add_argument( + "-output", + "--output", + dest="out_file", + action="store", + type=str, + default=None, + required=True, + help="The output file." + ) + parser.add_argument( + "-f", + "--fraction", + dest="fraction_of_optimum", + action="store", + type=float, + default=None, + required=True, + help="The fraction of optimum the FVA solutions should come within." + ) + parser.add_argument( + "-u", + "--uptake_constraints_file", + dest="uptake_constraints_file", + action="store", + type=str, + default=None, + required=False, + help="File containing new uptake constraits." + ) + + args = parser.parse_args() + + # Validate constraints file first if provided + constraints_df = None + if args.uptake_constraints_file is not None\ + and args.uptake_constraints_file != "None": + try: + constraints_df = pd.read_csv( + args.uptake_constraints_file, + sep=";", + header=0, + index_col=False + ) + + required_columns = ['reaction_id', 'lower_bound', 'upper_bound'] + missing_columns = [col for col in required_columns if + col not in constraints_df.columns] + + if missing_columns: + raise ValueError( + f"Constraints file is missing required columns: " + f"{', '.join(missing_columns)}. " + f"Required columns are: {', '.join(required_columns)}" + ) + except FileNotFoundError: + raise FileNotFoundError( + f"Constraints file not found: {args.uptake_constraints_file}" + ) + except pd.errors.EmptyDataError: + raise ValueError("Constraints file is empty") + except Exception as e: + raise ValueError(f"Error processing constraints file: {str(e)}") + + # Load model + cb_model = cobra.io.read_sbml_model(args.cb_model_location) + + # Apply constraints if they were loaded successfully + if constraints_df is not None: + for index, row in constraints_df.iterrows(): + cb_model.reactions.get_by_id( + row["reaction_id"]).lower_bound = float(row["lower_bound"]) + cb_model.reactions.get_by_id( + row["reaction_id"]).upper_bound = float(row["upper_bound"]) + + fraction_of_optimum = args.fraction_of_optimum + + # perform fva + fva_result = cobra.flux_analysis.flux_variability_analysis( + cb_model, + fraction_of_optimum=fraction_of_optimum + ) + + # add reaction names and ids to the dataframe + fva_result["reaction_id"] = fva_result.index + fva_result["reaction_name"] = fva_result["reaction_id"].apply( + lambda x: cb_model.reactions.get_by_id(x).name + ) + + # reorder the columns + fva_result = fva_result[[ + "reaction_id", "reaction_name", "minimum", "maximum" + ]] + + fva_result.to_csv(args.out_file, sep=";", index=False, header=True) + + +if __name__ == "__main__": + __main__() |
b |
diff -r 000000000000 -r b79cf44068bc gem_knockout.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gem_knockout.py Fri Dec 13 21:32:58 2024 +0000 |
[ |
@@ -0,0 +1,152 @@ +import argparse + +import cobra +import pandas as pd + + +def __main__(): + parser = argparse.ArgumentParser( + prog="FluxDistribution", + description="Performs FBA knockout analysis on a GEM.", + epilog="Adding an epilog, but doubt it's needed.", + ) + parser.add_argument( + "-m", + "--cb_model_location", + dest="cb_model_location", + action="store", + type=str, + default=None, + required=True, + help="The model to use." + ) + parser.add_argument( + "-output", + "--output", + dest="out_file", + action="store", + type=str, + default=None, + required=True, + help="The output file." + ) + parser.add_argument( + "-k", + "--knockout_type", + dest="knockout_type", + action="store", + type=str, + default="single", + required=False, + help="Type of knockout to perform, single or double" + ) + parser.add_argument( + "-g", + "--gene_knockouts", + dest="gene_knockouts", + action="store", + type=str, default=None, + required=False, + help="List of genes to knock out. Defaults to all." + ) + parser.add_argument( + "-u", + "--uptake_constraints_file", + dest="uptake_constraints_file", + action="store", + type=str, + default=None, + required=False, + help="File containing new uptake constraits." + ) + + args = parser.parse_args() + + # Reading the model + try: + cb_model = cobra.io.read_sbml_model(args.cb_model_location) + except Exception as e: + raise Exception( + "The model could not be read. " + "Ensure it is in correct SBML format." + ) from e + + # Verifying the genes are present in the model + gene_ids = [gene.id for gene in cb_model.genes] + + genes_to_knockout_1 = args.gene_knockouts.split(',')\ + if args.gene_knockouts is not None else [] + gene_bool = [ + True if gene in gene_ids else False for gene in genes_to_knockout_1 + ] + if not all(gene_bool): + print( + f'Found {sum(gene_bool)} of {len(genes_to_knockout_1)} genes ' + 'in the model.' + ) + raise Exception( + "One or more of the genes to knockout are not present " + "in the model." + ) + + # Adding all genes to knockout if none are specified + if genes_to_knockout_1 is None or len(genes_to_knockout_1) == 0: + genes_to_knockout_1 = [gene.id for gene in cb_model.genes] + # Applying uptake constraints + if (args.uptake_constraints_file is not None + and args.uptake_constraints_file != "None"): + constraints_df = pd.read_csv( + args.uptake_constraints_file, + sep=";", + header=0, + index_col=False + ) + for index, row in constraints_df.iterrows(): + reaction = cb_model.reactions.get_by_id(row["reaction_id"]) + reaction.lower_bound = row["lower_bound"] + reaction.upper_bound = row["upper_bound"] + + result = pd.DataFrame(columns=[ + "reaction_id", "ko_gene_id_1", "ko_gene_id_2", + "reaction", "wildtype_flux", "knockout_flux" + ]) + + if args.knockout_type == "single": + genes_to_knockout_2 = [0] + elif args.knockout_type == "double": + genes_to_knockout_2 = genes_to_knockout_1.copy() + else: + raise Exception( + f"Invalid knockout type {args.knockout_type}. " + "Only single and double are allowed." + ) + + # Wildtype pFBA + with cb_model as model: + wildtype_solution = model.optimize() + + # Performing gene knockouts + for gene1 in genes_to_knockout_1: + for gene2 in genes_to_knockout_2: + with cb_model as model: + model.genes.get_by_id(gene1).knock_out() + if args.knockout_type == "double": + model.genes.get_by_id(gene2).knock_out() + solution = model.optimize() + for reaction in model.reactions: + result = pd.concat([result, pd.DataFrame([{ + "reaction_id": reaction.id, + "ko_gene_id_1": gene1, + "ko_gene_id_2": gene2 + if args.knockout_type == "double" else None, + "reaction": reaction.reaction, + "wildtype_flux": wildtype_solution.fluxes[reaction.id], + "knockout_flux": solution.fluxes[reaction.id], + }])], ignore_index=True) + + # Writing the results to file + result.to_csv(args.out_file, sep=";", index=False) + + +if __name__ == "__main__": + __main__() |
b |
diff -r 000000000000 -r b79cf44068bc gem_macros.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gem_macros.xml Fri Dec 13 21:32:58 2024 +0000 |
b |
@@ -0,0 +1,75 @@ +<macros> + <!-- Tokens --> + <token name="@VERSION@">0.29.1</token> + <token name="@PROFILE@">23.0</token> + + <!-- Add version commands for different tools --> + <xml name="version_command_cobra"> + <version_command>echo '@VERSION@'</version_command> + </xml> + + <xml name="version_command_escher"> + <version_command>python -c 'from escher import __version__; print(__version__)'</version_command> + </xml> + + <xml name="version_command_memote"> + <version_command>python -c 'from memote import __version__; print(__version__)'</version_command> + </xml> + + <!-- Version command uses cobra requirement version --> + <xml name="version_command"> + <version_command>echo '@VERSION@'</version_command> + </xml> + + <!-- Setting cobra requirement to use version token --> + <xml name="requirements"> + <requirements> + <requirement type="package" version="@VERSION@">cobra</requirement> + <requirement type="package" version="2.2.3">pandas</requirement> + <requirement type="package" version="0.17.0">memote</requirement> + <requirement type="package" version="1.7.3">escher</requirement> + </requirements> + </xml> + + <!-- Common inputs --> + <xml name="input_model"> + <param format="sbml" name="cb_model_location" type="data" label="Model to analyze"/> + </xml> + + <xml name="input_uptake_constraints"> + <param format="csv" name="uptake_constraints_file" type="data" label="Uptake constraints CSV file" optional="true"/> + </xml> + + <!-- Common outputs --> + <xml name="output"> + <data name="output" format="csv" label="${tool.name} on ${on_string}"/> + </xml> + + <!-- Common test elements --> + <xml name="test_invalid_model"> + <test expect_failure="true"> + <param name="cb_model_location" value="invalid_format.txt"/> + <assert_stderr> + <has_text text="The model could not be read"/> + </assert_stderr> + </test> + </xml> + + <!-- Citations --> + <xml name="citation_cobrapy"> + <citation type="doi">10.1186/1752-0509-7-74</citation> + </xml> + + <xml name="citation_pandas"> + <citation type="doi">10.5281/zenodo.3509134</citation> + </xml> + + <xml name="citation_escher"> + <citation type="doi">10.1371/journal.pcbi.1004321</citation> + </xml> + + <xml name="citation_memote"> + <citation type="doi">10.1038/s41587-020-0446-y</citation> + </xml> + +</macros> |
b |
diff -r 000000000000 -r b79cf44068bc gem_phenotype_phase_plane.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gem_phenotype_phase_plane.py Fri Dec 13 21:32:58 2024 +0000 |
[ |
@@ -0,0 +1,151 @@ +import argparse + +import cobra +import pandas as pd + + +def __main__(): + parser = argparse.ArgumentParser( + prog="ExpectedGrowthRate", + description="This program calculates the production envelope of a GEM", + epilog="Adding an epilog, but doubt it's needed.", + ) + parser.add_argument( + "-m", + "--cb_model_location", + dest="cb_model_location", + action="store", + type=str, + default=None, + required=True, + help="The model to use." + ) + parser.add_argument( + "-output_csv", + "--output_csv", + dest="out_file_csv", + action="store", + type=str, + default=None, + required=True, + help="The output csv file name." + ) + parser.add_argument( + "-r1", + "--reaction1", + dest="reaction1", + action="store", + type=str, + default=None, + required=True, + help="The first reaction to scan." + ) + parser.add_argument( + "-r2", + "--reaction2", + dest="reaction2", + action="store", + type=str, + default=None, + required=True, + help="The second reaction to scan." + ) + parser.add_argument( + "-p", + "--points", + dest="points", + action="store", + type=int, + default=10, + required=False, + help="The number of points to scan." + ) + parser.add_argument( + "-c", + "--objective", + dest="objective", + action="store", + type=str, + default=None, + required=False, + help="The reaction to use as objective." + ) + parser.add_argument( + "-u", + "--uptake_constraints_file", + dest="uptake_constraints_file", + action="store", + type=str, + default=None, + required=False, + help="The file containing the uptake constraints." + ) + + args = parser.parse_args() + try: + assert len(vars(args)) == 7 + except AssertionError: + raise Exception( + f"{len(vars(args))} arguments were received. 7 were expected." + ) + + try: + cb_model = cobra.io.read_sbml_model(args.cb_model_location) + except Exception as e: + raise Exception( + "The model could not be read. Ensure it is in correct SBML format." + ) from e + + # set the uptake constraints if provided + if (args.uptake_constraints_file is not None + and args.uptake_constraints_file != "None"): + constraints_df = pd.read_csv( + args.uptake_constraints_file, + sep=";", + header=0, + index_col=False + ) + for index, row in constraints_df.iterrows(): + cb_model.reactions.get_by_id(row["reaction_id"])\ + .lower_bound = row["lower_bound"] + cb_model.reactions.get_by_id(row["reaction_id"])\ + .upper_bound = row["upper_bound"] + + # get the reactions + reactions = [args.reaction1, args.reaction2] + + # checking if reactions are in model + for reaction in reactions: + if reaction not in cb_model.reactions: + raise Exception( + f"Reaction {reaction} not found in model " + f"{args.cb_model_location.split('/')[-1]}" + ) + + # get the points + points = args.points + if not isinstance(points, int): + raise Exception("Points must be an integer") + if points < 1: + raise Exception("Must have at least one point in the phase plane") + + # perform phenotype phase plane analysis + if args.objective is not None and args.objective != "None" \ + and args.objective != '': + obj = args.objective + else: + obj = None + + results = cobra.flux_analysis.phenotype_phase_plane.production_envelope( + model=cb_model, + reactions=reactions, + points=points, + objective=obj, + ) + + # save the results + results.to_csv(args.out_file_csv, sep=";", header=True, index=False) + + +if __name__ == "__main__": + __main__() |
b |
diff -r 000000000000 -r b79cf44068bc test-data/e_coli_core_test_map.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/e_coli_core_test_map.json Fri Dec 13 21:32:58 2024 +0000 |
[ |
b'@@ -0,0 +1,1 @@\n+[{"map_name":"e_coli_core.Core metabolism","map_id":"0df3827fde8464e80f455a773a52c274","map_description":"E. coli core metabolic network\\nLast Modified Thu Dec 12 2024 23:15:48 GMT+0100 (Central European Standard Time)","homepage":"https://escher.github.io","schema":"https://escher.github.io/escher/jsonschema/1-0-0#"},{"reactions":{"1576693":{"name":"Phosphoglycerate kinase","bigg_id":"PGK","reversibility":true,"label_x":1065,"label_y":2715,"gene_reaction_rule":"b2926","genes":[{"bigg_id":"b2926","name":"pgk"}],"metabolites":[{"coefficient":-1,"bigg_id":"3pg_c"},{"coefficient":1,"bigg_id":"13dpg_c"},{"coefficient":-1,"bigg_id":"atp_c"},{"coefficient":1,"bigg_id":"adp_c"}],"segments":{"291":{"from_node_id":"1576835","to_node_id":"1576836","b1":null,"b2":null},"292":{"from_node_id":"1576836","to_node_id":"1576834","b1":null,"b2":null},"293":{"from_node_id":"1576485","to_node_id":"1576835","b1":{"y":2822.4341649025255,"x":1055},"b2":{"y":2789.230249470758,"x":1055}},"294":{"from_node_id":"1576486","to_node_id":"1576835","b1":{"y":2825,"x":1055},"b2":{"y":2790,"x":1055}},"295":{"from_node_id":"1576834","to_node_id":"1576487","b1":{"y":2650,"x":1055},"b2":{"y":2615,"x":1055}},"296":{"from_node_id":"1576834","to_node_id":"1576488","b1":{"y":2650.769750529242,"x":1055},"b2":{"y":2617.5658350974745,"x":1055}}}},"1576694":{"name":"Phosphogluconate dehydrogenase","bigg_id":"GND","reversibility":false,"label_x":1930.5045166015625,"label_y":1313.710205078125,"gene_reaction_rule":"b2029","genes":[{"bigg_id":"b2029","name":"gnd"}],"metabolites":[{"coefficient":1,"bigg_id":"ru5p__D_c"},{"coefficient":1,"bigg_id":"nadph_c"},{"coefficient":1,"bigg_id":"co2_c"},{"coefficient":-1,"bigg_id":"nadp_c"},{"coefficient":-1,"bigg_id":"6pgc_c"}],"segments":{"297":{"from_node_id":"1576838","to_node_id":"1576837","b1":null,"b2":null},"298":{"from_node_id":"1576837","to_node_id":"1576839","b1":null,"b2":null},"299":{"from_node_id":"1576489","to_node_id":"1576838","b1":{"y":1265,"x":1884.7984674554473},"b2":{"y":1265,"x":1921.339540236634}},"300":{"from_node_id":"1576490","to_node_id":"1576838","b1":{"y":1265,"x":1882},"b2":{"y":1265,"x":1920.5}},"301":{"from_node_id":"1576839","to_node_id":"1576491","b1":{"y":1265,"x":1992.660459763366},"b2":{"y":1265,"x":2029.2015325445527}},"302":{"from_node_id":"1576839","to_node_id":"1576492","b1":{"y":1265,"x":1996.2093727122985},"b2":{"y":1265,"x":2041.0312423743285}},"303":{"from_node_id":"1576839","to_node_id":"1576493","b1":{"y":1265,"x":2003.7},"b2":{"y":1265,"x":2066}}}},"1576695":{"name":"O2 transport diffusion ","bigg_id":"O2t","reversibility":true,"label_x":4557.1943359375,"label_y":1635.4964599609375,"gene_reaction_rule":"s0001","genes":[{"bigg_id":"s0001","name":"None"}],"metabolites":[{"coefficient":1,"bigg_id":"o2_c"},{"coefficient":-1,"bigg_id":"o2_e"}],"segments":{"304":{"from_node_id":"1576494","to_node_id":"1576840","b1":{"y":1660,"x":4821.5},"b2":{"y":1660,"x":4755}},"305":{"from_node_id":"1576840","to_node_id":"1576495","b1":{"y":1660,"x":4610.5},"b2":{"y":1660,"x":4495}}}},"1576696":{"name":"NAD P transhydrogenase","bigg_id":"THD2","reversibility":false,"label_x":3532.891845703125,"label_y":872.8489990234375,"gene_reaction_rule":"b1602 and b1603","genes":[{"bigg_id":"b1602","name":"pntB"},{"bigg_id":"b1603","name":"pntA"}],"metabolites":[{"coefficient":-2,"bigg_id":"h_e"},{"coefficient":-1,"bigg_id":"nadp_c"},{"coefficient":-1,"bigg_id":"nadh_c"},{"coefficient":1,"bigg_id":"nadph_c"},{"coefficient":2,"bigg_id":"h_c"},{"coefficient":1,"bigg_id":"nad_c"}],"segments":{"306":{"from_node_id":"1576842","to_node_id":"1576841","b1":null,"b2":null},"307":{"from_node_id":"1576841","to_node_id":"1576843","b1":null,"b2":null},"308":{"from_node_id":"1576496","to_node_id":"1576842","b1":{"y":580.5856339661426,"x":3331.1220703125},"b2":{"y":724.5066228070302,"x":3510}},"309":{"from_node_id":"1576497","to_node_id":"1576842","b1":{"y":654.7419446101471,"x":3418.143798828125},"b2":{"y":750.137689'..b'hate","label_x":5052.6396484375,"label_y":4477.9873046875,"node_is_primary":false},"1577085":{"node_type":"metabolite","x":4988.05859375,"y":4509.18115234375,"bigg_id":"pyr_c","name":"Pyruvate","label_x":4962.07666015625,"label_y":4488.5498046875,"node_is_primary":false},"1577086":{"node_type":"metabolite","x":4893.27099609375,"y":4529.25048828125,"bigg_id":"nad_c","name":"Nicotinamide adenine dinucleotide","label_x":4860.95166015625,"label_y":4501.22509765625,"node_is_primary":false},"1577087":{"node_type":"metabolite","x":5208.85205078125,"y":4931.947265625,"bigg_id":"coa_c","name":"Coenzyme A","label_x":5175.48828125,"label_y":4975.3330078125,"node_is_primary":false},"1577088":{"node_type":"metabolite","x":4783.69580078125,"y":4544.03759765625,"bigg_id":"oaa_c","name":"Oxaloacetate","label_x":4770.38916015625,"label_y":4522.349609375,"node_is_primary":false},"1577089":{"node_type":"metabolite","x":4700.52734375,"y":4559.88134765625,"bigg_id":"g6p_c","name":"D-Glucose 6-phosphate","label_x":4679.8271484375,"label_y":4537.1376953125,"node_is_primary":false},"1577090":{"node_type":"metabolite","x":5134.0517578125,"y":4897.1259765625,"bigg_id":"nadh_c","name":"Nicotinamide adenine dinucleotide - reduced","label_x":5078.88623046875,"label_y":4936.322265625,"node_is_primary":false},"1577091":{"node_type":"metabolite","x":5481.046875,"y":4979.51025390625,"bigg_id":"akg_c","name":"2-Oxoglutarate","label_x":5497.31591796875,"label_y":5004.2978515625,"node_is_primary":false},"1577092":{"node_type":"metabolite","x":4601.51416015625,"y":4576.78173828125,"bigg_id":"accoa_c","name":"Acetyl-CoA","label_x":4556.52001953125,"label_y":4549.81298828125,"node_is_primary":false},"1577093":{"node_type":"metabolite","x":4508.83935546875,"y":4602.1318359375,"bigg_id":"3pg_c","name":"3-Phospho-D-glycerate","label_x":4459.6201171875,"label_y":4576.21923828125,"node_is_primary":false},"1577094":{"node_type":"metabolite","x":4414.0517578125,"y":4629.59423828125,"bigg_id":"pep_c","name":"Phosphoenolpyruvate","label_x":4379.6201171875,"label_y":4607.90673828125,"node_is_primary":false},"1577095":{"node_type":"metabolite","x":4332.9951171875,"y":4650.7197265625,"bigg_id":"gln__L_c","name":"L-Glutamine","label_x":4253.14453125,"label_y":4627.97607421875,"node_is_primary":false},"1577096":{"node_type":"metabolite","x":5028.71435546875,"y":4864.818359375,"bigg_id":"nadp_c","name":"Nicotinamide adenine dinucleotide phosphate","label_x":4968.08447265625,"label_y":4902.36181640625,"node_is_primary":false},"1577097":{"node_type":"metabolite","x":4267.78271484375,"y":4682.4072265625,"bigg_id":"nadph_c","name":"Nicotinamide adenine dinucleotide phosphate - reduced","label_x":4203.775390625,"label_y":4664.94482421875,"node_is_primary":false},"1577098":{"node_type":"metabolite","x":4933.43505859375,"y":4831.37548828125,"bigg_id":"pi_c","name":"Phosphate","label_x":4884.8583984375,"label_y":4859.1142578125,"node_is_primary":false},"1577099":{"node_type":"multimarker","x":3055.6239109998846,"y":4023.6457547875243},"1577100":{"node_type":"midmarker","x":3074.275683525833,"y":4030.8645761345497},"1577101":{"node_type":"multimarker","x":3092.9274560517806,"y":4038.0833974815746},"1577102":{"node_type":"metabolite","x":3188.1170476587818,"y":3976.144484067998,"bigg_id":"h2o_c","name":"H2O","label_x":3189.1795476587818,"label_y":3930.712355161748,"node_is_primary":false},"1577103":{"node_type":"metabolite","x":3197.4642088485407,"y":4053.2845721909744,"bigg_id":"acon_C_c","name":"Cis-Aconitate","label_x":3156.1556150985407,"label_y":4098.026271409724,"node_is_primary":true},"1577104":{"node_type":"multimarker","x":3294.488060371458,"y":4035.7165277261324},"1577105":{"node_type":"midmarker","x":3312.895717745038,"y":4027.896160086635},"1577106":{"node_type":"multimarker","x":3331.3033751186185,"y":4020.0757924471372}},"text_labels":{},"canvas":{"x":7.857062530517567,"y":314.36893920898433,"width":5894.515691375733,"height":4860.457037353515}}]\n\\ No newline at end of file\n' |
b |
diff -r 000000000000 -r b79cf44068bc test-data/expected_single_knockout.csv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/expected_single_knockout.csv Fri Dec 13 21:32:58 2024 +0000 |
b |
b'@@ -0,0 +1,13016 @@\n+reaction_id;ko_gene_id_1;ko_gene_id_2;reaction;wildtype_flux;knockout_flux\n+ACALD;b1241;;acald_c + coa_c + nad_c <=> accoa_c + h_c + nadh_c;0.0;0.0\n+ACALDt;b1241;;acald_e <=> acald_c;0.0;0.0\n+ACKr;b1241;;ac_c + atp_c <=> actp_c + adp_c;3.1922147150048876e-14;0.0\n+ACONTa;b1241;;cit_c <=> acon_C_c + h2o_c;6.007249575350396;6.007249575350337\n+ACONTb;b1241;;acon_C_c + h2o_c <=> icit_c;6.007249575350396;6.007249575350338\n+ACt2r;b1241;;ac_e + h_e <=> ac_c + h_c;3.192214715004888e-14;0.0\n+ADK1;b1241;;amp_c + atp_c <=> 2.0 adp_c;0.0;0.0\n+AKGDH;b1241;;akg_c + coa_c + nad_c --> co2_c + nadh_c + succoa_c;5.064375661482158;5.064375661482093\n+AKGt2r;b1241;;akg_e + h_e <=> akg_c + h_c;0.0;0.0\n+ALCD2x;b1241;;etoh_c + nad_c <=> acald_c + h_c + nadh_c;0.0;0.0\n+ATPM;b1241;;atp_c + h2o_c --> adp_c + h_c + pi_c;8.39;8.39\n+ATPS4r;b1241;;adp_c + 4.0 h_e + pi_c <=> atp_c + h2o_c + 3.0 h_c;45.51400977451776;45.514009774517476\n+Biomass_Ecoli_core;b1241;;1.496 3pg_c + 3.7478 accoa_c + 59.81 atp_c + 0.361 e4p_c + 0.0709 f6p_c + 0.129 g3p_c + 0.205 g6p_c + 0.2557 gln__L_c + 4.9414 glu__L_c + 59.81 h2o_c + 3.547 nad_c + 13.0279 nadph_c + 1.7867 oaa_c + 0.5191 pep_c + 2.8328 pyr_c + 0.8977 r5p_c --> 59.81 adp_c + 4.1182 akg_c + 3.7478 coa_c + 59.81 h_c + 3.547 nadh_c + 13.0279 nadp_c + 59.81 pi_c;0.8739215069684279;0.8739215069684305\n+CO2t;b1241;;co2_e <=> co2_c;-22.809833310205086;-22.80983331020497\n+CS;b1241;;accoa_c + h2o_c + oaa_c --> cit_c + coa_c + h_c;6.007249575350396;6.007249575350337\n+CYTBD;b1241;;2.0 h_c + 0.5 o2_c + q8h2_c --> h2o_c + 2.0 h_e + q8_c;43.59898531199778;43.59898531199753\n+D_LACt2;b1241;;h_e + lac__D_e <=> h_c + lac__D_c;0.0;0.0\n+ENO;b1241;;2pg_c <=> h2o_c + pep_c;14.716139568742859;14.716139568742836\n+ETOHt2r;b1241;;etoh_e + h_e <=> etoh_c + h_c;0.0;0.0\n+EX_ac_e;b1241;;ac_e --> ;0.0;0.0\n+EX_acald_e;b1241;;acald_e --> ;0.0;0.0\n+EX_akg_e;b1241;;akg_e --> ;0.0;0.0\n+EX_co2_e;b1241;;co2_e <=> ;22.809833310205086;22.80983331020497\n+EX_etoh_e;b1241;;etoh_e --> ;0.0;0.0\n+EX_for_e;b1241;;for_e --> ;0.0;0.0\n+EX_fru_e;b1241;;fru_e --> ;0.0;0.0\n+EX_fum_e;b1241;;fum_e --> ;0.0;0.0\n+EX_glc__D_e;b1241;;glc__D_e <=> ;-10.0;-10.0\n+EX_gln__L_e;b1241;;gln__L_e --> ;0.0;0.0\n+EX_glu__L_e;b1241;;glu__L_e --> ;0.0;0.0\n+EX_h_e;b1241;;h_e <=> ;17.530865429786523;17.530865429786648\n+EX_h2o_e;b1241;;h2o_e <=> ;29.175827135565836;29.175827135565825\n+EX_lac__D_e;b1241;;lac__D_e --> ;0.0;0.0\n+EX_mal__L_e;b1241;;mal__L_e --> ;0.0;0.0\n+EX_nh4_e;b1241;;nh4_e <=> ;-4.765319193197444;-4.765319193197457\n+EX_o2_e;b1241;;o2_e <=> ;-21.799492655998886;-21.799492655998762\n+EX_pi_e;b1241;;pi_e <=> ;-3.214895047684769;-3.214895047684796\n+EX_pyr_e;b1241;;pyr_e --> ;0.0;0.0\n+EX_succ_e;b1241;;succ_e --> ;0.0;0.0\n+FBA;b1241;;fdp_c <=> dhap_c + g3p_c;7.477381962160304;7.477381962160286\n+FBP;b1241;;fdp_c + h2o_c --> f6p_c + pi_c;0.0;0.0\n+FORt2;b1241;;for_e + h_e --> for_c + h_c;0.0;0.0\n+FORti;b1241;;for_c --> for_e;0.0;0.0\n+FRD7;b1241;;fum_c + q8h2_c --> q8_c + succ_c;0.0;0.0\n+FRUpts2;b1241;;fru_e + pep_c --> f6p_c + pyr_c;0.0;0.0\n+FUM;b1241;;fum_c + h2o_c <=> mal__L_c;5.064375661482159;5.064375661482093\n+FUMt2_2;b1241;;fum_e + 2.0 h_e --> fum_c + 2.0 h_c;0.0;0.0\n+G6PDH2r;b1241;;g6p_c + nadp_c <=> 6pgl_c + h_c + nadph_c;4.959984944574603;4.959984944574654\n+GAPD;b1241;;g3p_c + nad_c + pi_c <=> 13dpg_c + h_c + nadh_c;16.023526143167626;16.023526143167608\n+GLCpts;b1241;;glc__D_e + pep_c --> g6p_c + pyr_c;10.000000000000002;10.000000000000002\n+GLNS;b1241;;atp_c + glu__L_c + nh4_c --> adp_c + gln__L_c + h_c + pi_c;0.22346172933182715;0.22346172933182762\n+GLNabc;b1241;;atp_c + gln__L_e + h2o_c --> adp_c + gln__L_c + h_c + pi_c;0.0;0.0\n+GLUDy;b1241;;glu__L_c + h2o_c + nadp_c <=> akg_c + h_c + nadph_c + nh4_c;-4.541857463865617;-4.54185746386563\n+GLUN;b1241;;gln__L_c + h2o_c --> glu__L_c + nh4_c;0.0;0.0\n+GLUSy;b1241;;akg_c + gln__L_c + h_c + nadph_c --> 2.0 glu__L_c + nadp_c;0.0;0.0\n+GLUt2r;b1241;;glu__L_e + h_e <=> glu__L_c + h_c;0.0;0.0\n+GND;b1241;;6pgc_c + nadp'..b'9;;fum_c + q8h2_c --> q8_c + succ_c;0.0;0.0\n+FRUpts2;b3919;;fru_e + pep_c --> f6p_c + pyr_c;0.0;0.0\n+FUM;b3919;;fum_c + h2o_c <=> mal__L_c;5.064375661482159;1.8194300213456418e-15\n+FUMt2_2;b3919;;fum_e + 2.0 h_e --> fum_c + 2.0 h_c;0.0;0.0\n+G6PDH2r;b3919;;g6p_c + nadp_c <=> 6pgl_c + h_c + nadph_c;4.959984944574603;27.899083343893903\n+GAPD;b3919;;g3p_c + nad_c + pi_c <=> 13dpg_c + h_c + nadh_c;16.023526143167626;8.828764133541728\n+GLCpts;b3919;;glc__D_e + pep_c --> g6p_c + pyr_c;10.000000000000002;10.000000000000002\n+GLNS;b3919;;atp_c + glu__L_c + nh4_c --> adp_c + gln__L_c + h_c + pi_c;0.22346172933182715;0.18002224756755264\n+GLNabc;b3919;;atp_c + gln__L_e + h2o_c --> adp_c + gln__L_c + h_c + pi_c;0.0;0.0\n+GLUDy;b3919;;glu__L_c + h2o_c + nadp_c <=> akg_c + h_c + nadph_c + nh4_c;-4.541857463865617;-3.6589504217181372\n+GLUN;b3919;;gln__L_c + h2o_c --> glu__L_c + nh4_c;0.0;0.0\n+GLUSy;b3919;;akg_c + gln__L_c + h_c + nadph_c --> 2.0 glu__L_c + nadp_c;0.0;0.0\n+GLUt2r;b3919;;glu__L_e + h_e <=> glu__L_c + h_c;0.0;0.0\n+GND;b3919;;6pgc_c + nadp_c --> co2_c + nadph_c + ru5p__D_c;4.959984944574602;27.8990833438939\n+H2Ot;b3919;;h2o_e <=> h2o_c;-29.175827135565836;-35.16784240836959\n+ICDHyr;b3919;;icit_c + nadp_c <=> akg_c + co2_c + nadph_c;6.007249575350396;0.7595854630451014\n+ICL;b3919;;icit_c --> glx_c + succ_c;0.0;0.0\n+LDH_D;b3919;;lac__D_c + nad_c <=> h_c + nadh_c + pyr_c;-2.8851667222789664e-15;0.0\n+MALS;b3919;;accoa_c + glx_c + h2o_c --> coa_c + h_c + mal__L_c;0.0;0.0\n+MALt2_2;b3919;;2.0 h_e + mal__L_e --> 2.0 h_c + mal__L_c;0.0;0.0\n+MDH;b3919;;mal__L_c + nad_c <=> h_c + nadh_c + oaa_c;5.064375661482158;1.8194300213456418e-15\n+ME1;b3919;;mal__L_c + nad_c --> co2_c + nadh_c + pyr_c;0.0;0.0\n+ME2;b3919;;mal__L_c + nadp_c --> co2_c + nadph_c + pyr_c;0.0;0.0\n+NADH16;b3919;;4.0 h_c + nadh_c + q8_c --> 3.0 h_e + nad_c + q8h2_c;38.53460965051561;58.450837099931015\n+NADTRHD;b3919;;nad_c + nadph_c --> nadh_c + nadp_c;0.0;43.72667877610217\n+NH4t;b3919;;nh4_e <=> nh4_c;4.765319193197444;3.8389726692856874\n+O2t;b3919;;o2_e <=> o2_c;21.799492655998886;29.225418549965504\n+PDH;b3919;;coa_c + nad_c + pyr_c --> accoa_c + co2_c + nadh_c;9.282532599166657;3.3981751362311448\n+PFK;b3919;;atp_c + f6p_c --> adp_c + fdp_c + h_c;7.477381962160304;-3.3456810303021106e-15\n+PFL;b3919;;coa_c + pyr_c --> accoa_c + for_c;0.0;0.0\n+PGI;b3919;;g6p_c <=> f6p_c;4.860861146496871;-18.043410918204998\n+PGK;b3919;;3pg_c + atp_c <=> 13dpg_c + adp_c;-16.02352614316763;-8.828764133541728\n+PGL;b3919;;6pgl_c + h2o_c --> 6pgc_c + h_c;4.959984944574602;27.899083343893903\n+PGM;b3919;;2pg_c <=> 3pg_c;-14.716139568742859;-7.775524859544626\n+PIt2r;b3919;;h_e + pi_e <=> h_c + pi_c;3.214895047684769;2.5899407200890217\n+PPC;b3919;;co2_c + h2o_c + pep_c --> h_c + oaa_c + pi_c;2.504309470368726;2.017488277784812\n+PPCK;b3919;;atp_c + oaa_c --> adp_c + co2_c + pep_c;0.0;0.0\n+PPS;b3919;;atp_c + h2o_c + pyr_c --> amp_c + 2.0 h_c + pep_c + pi_c;0.0;4.60742899787381\n+PTAr;b3919;;accoa_c + pi_c <=> actp_c + coa_c;-1.2124702739418495e-14;0.0\n+PYK;b3919;;adp_c + h_c + pep_c --> atp_c + pyr_c;1.758177444106819;0.0\n+PYRt2;b3919;;h_e + pyr_e <=> h_c + pyr_c;-7.59778544700626e-16;0.0\n+RPE;b3919;;ru5p__D_c <=> xu5p__D_c;2.6784818505074948;18.0933271378082\n+RPI;b3919;;r5p_c <=> ru5p__D_c;-2.2815030940671064;-9.8057562060857\n+SUCCt2_2;b3919;;2.0 h_e + succ_e --> 2.0 h_c + succ_c;0.0;0.0\n+SUCCt3;b3919;;h_e + succ_c --> h_c + succ_e;0.0;0.0\n+SUCDi;b3919;;q8_c + succ_c --> fum_c + q8h2_c;5.064375661482159;1.819430021345642e-15\n+SUCOAS;b3919;;atp_c + coa_c + succ_c <=> adp_c + pi_c + succoa_c;-5.064375661482159;-5.68756655051901e-15\n+TALA;b3919;;g3p_c + s7p_c <=> e4p_c + f6p_c;1.4969837572615485;9.173742237992654\n+THD2;b3919;;2.0 h_e + nadh_c + nadp_c --> 2.0 h_c + nad_c + nadph_c;0.0;0.0\n+TKT1;b3919;;r5p_c + xu5p__D_c <=> g3p_c + s7p_c;1.4969837572615483;9.173742237992654\n+TKT2;b3919;;e4p_c + xu5p__D_c <=> f6p_c + g3p_c;1.1814980932459462;8.919584899815547\n+TPI;b3919;;dhap_c --> g3p_c;7.477381962160304;0.0\n' |
b |
diff -r 000000000000 -r b79cf44068bc test-data/invalid_format.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/invalid_format.txt Fri Dec 13 21:32:58 2024 +0000 |
b |
@@ -0,0 +1,1 @@ +This is just a junk file for testing. \ No newline at end of file |
b |
diff -r 000000000000 -r b79cf44068bc test-data/textbook_model_cobrapy.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/textbook_model_cobrapy.xml Fri Dec 13 21:32:58 2024 +0000 |
b |
b'@@ -0,0 +1,5467 @@\n+<?xml version="1.0" encoding="UTF-8"?>\n+<sbml xmlns="http://www.sbml.org/sbml/level3/version1/core" xmlns:fbc="http://www.sbml.org/sbml/level3/version1/fbc/version2" metaid="meta_" sboTerm="SBO:0000624" level="3" version="1" fbc:required="false">\n+ <model metaid="meta_e_coli_core" id="e_coli_core" fbc:strict="true">\n+ <listOfUnitDefinitions>\n+ <unitDefinition id="mmol_per_gDW_per_hr">\n+ <listOfUnits>\n+ <unit kind="mole" exponent="1" scale="-3" multiplier="1"/>\n+ <unit kind="gram" exponent="-1" scale="0" multiplier="1"/>\n+ <unit kind="second" exponent="-1" scale="0" multiplier="3600"/>\n+ </listOfUnits>\n+ </unitDefinition>\n+ </listOfUnitDefinitions>\n+ <listOfCompartments>\n+ <compartment id="c" name="cytosol" constant="true"/>\n+ <compartment id="e" name="extracellular" constant="true"/>\n+ </listOfCompartments>\n+ <listOfSpecies>\n+ <species metaid="meta_M_13dpg_c" id="M_13dpg_c" name="3-Phospho-D-glyceroyl phosphate" compartment="c" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false" fbc:charge="-4" fbc:chemicalFormula="C3H4O10P2">\n+ <annotation>\n+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:vCard4="http://www.w3.org/2006/vcard/ns#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/">\n+ <rdf:Description rdf:about="#meta_M_13dpg_c">\n+ <bqbiol:is>\n+ <rdf:Bag>\n+ <rdf:li rdf:resource="https://identifiers.org/bigg.metabolite/13dpg"/>\n+ <rdf:li rdf:resource="https://identifiers.org/biocyc/DPG"/>\n+ <rdf:li rdf:resource="https://identifiers.org/chebi/CHEBI:16001"/>\n+ <rdf:li rdf:resource="https://identifiers.org/chebi/CHEBI:1658"/>\n+ <rdf:li rdf:resource="https://identifiers.org/chebi/CHEBI:20189"/>\n+ <rdf:li rdf:resource="https://identifiers.org/chebi/CHEBI:57604"/>\n+ <rdf:li rdf:resource="https://identifiers.org/chebi/CHEBI:11881"/>\n+ <rdf:li rdf:resource="https://identifiers.org/hmdb/HMDB01270"/>\n+ <rdf:li rdf:resource="https://identifiers.org/kegg.compound/C00236"/>\n+ <rdf:li rdf:resource="https://identifiers.org/pubchem.substance/3535"/>\n+ <rdf:li rdf:resource="https://identifiers.org/reactome/REACT_29800"/>\n+ <rdf:li rdf:resource="https://identifiers.org/seed.compound/cpd00203"/>\n+ <rdf:li rdf:resource="https://identifiers.org/unipathway.compound/UPC00236"/>\n+ </rdf:Bag>\n+ </bqbiol:is>\n+ </rdf:Description>\n+ </rdf:RDF>\n+ </annotation>\n+ </species>\n+ <species metaid="meta_M_2pg_c" id="M_2pg_c" name="D-Glycerate 2-phosphate" compartment="c" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false" fbc:charge="-3" fbc:chemicalFormula="C3H4O7P">\n+ <annotation>\n+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:vCard4="http://www.w3.org/2006/vcard/ns#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/">\n+ <rdf:Description rdf:about="#meta_M_2pg_c">\n+ <bqbiol:is>\n+ <rdf:Bag>\n+ <rdf:li rdf:resource="https://identifiers.org/bigg.metabolite/2pg"/>\n+ <rdf:li rdf:resource="https://identifiers.org/biocyc/2-PG"/>\n+ <rdf:li rdf:resource="https://identifiers.org/chebi/CHEBI:1267"/>\n+ <rdf:li rdf:resource="https://identifiers.org/chebi/CHEBI:58289"/>\n+ <rdf:li rdf:resource="https://identifier'..b':li rdf:resource="https://identifiers.org/ncbiprotein/1652853"/>\n+ <rdf:li rdf:resource="https://identifiers.org/ncbiprotein/1673321"/>\n+ </rdf:Bag>\n+ </bqbiol:is>\n+ </rdf:Description>\n+ </rdf:RDF>\n+ </annotation>\n+ </fbc:geneProduct>\n+ <fbc:geneProduct fbc:id="G_b0721" fbc:name="sdhC" fbc:label="G_b0721"/>\n+ <fbc:geneProduct fbc:id="G_b0723" fbc:name="sdhA" fbc:label="G_b0723"/>\n+ <fbc:geneProduct metaid="meta_G_b0728" fbc:id="G_b0728" fbc:name="sucC" fbc:label="G_b0728">\n+ <annotation>\n+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:vCard4="http://www.w3.org/2006/vcard/ns#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/">\n+ <rdf:Description rdf:about="#meta_G_b0728">\n+ <bqbiol:is>\n+ <rdf:Bag>\n+ <rdf:li rdf:resource="https://identifiers.org/ncbiprotein/1652018"/>\n+ </rdf:Bag>\n+ </bqbiol:is>\n+ </rdf:Description>\n+ </rdf:RDF>\n+ </annotation>\n+ </fbc:geneProduct>\n+ <fbc:geneProduct metaid="meta_G_b0729" fbc:id="G_b0729" fbc:name="sucD" fbc:label="G_b0729">\n+ <annotation>\n+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:vCard4="http://www.w3.org/2006/vcard/ns#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/">\n+ <rdf:Description rdf:about="#meta_G_b0729">\n+ <bqbiol:is>\n+ <rdf:Bag>\n+ <rdf:li rdf:resource="https://identifiers.org/ncbiprotein/1653466"/>\n+ </rdf:Bag>\n+ </bqbiol:is>\n+ </rdf:Description>\n+ </rdf:RDF>\n+ </annotation>\n+ </fbc:geneProduct>\n+ <fbc:geneProduct fbc:id="G_b2464" fbc:name="talA" fbc:label="G_b2464"/>\n+ <fbc:geneProduct metaid="meta_G_b0008" fbc:id="G_b0008" fbc:name="talB" fbc:label="G_b0008">\n+ <annotation>\n+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:vCard4="http://www.w3.org/2006/vcard/ns#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/">\n+ <rdf:Description rdf:about="#meta_G_b0008">\n+ <bqbiol:is>\n+ <rdf:Bag>\n+ <rdf:li rdf:resource="https://identifiers.org/ncbiprotein/1651885"/>\n+ </rdf:Bag>\n+ </bqbiol:is>\n+ </rdf:Description>\n+ </rdf:RDF>\n+ </annotation>\n+ </fbc:geneProduct>\n+ <fbc:geneProduct metaid="meta_G_b2935" fbc:id="G_b2935" fbc:name="tktA" fbc:label="G_b2935">\n+ <annotation>\n+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:vCard4="http://www.w3.org/2006/vcard/ns#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/">\n+ <rdf:Description rdf:about="#meta_G_b2935">\n+ <bqbiol:is>\n+ <rdf:Bag>\n+ <rdf:li rdf:resource="https://identifiers.org/ncbiprotein/1652388"/>\n+ </rdf:Bag>\n+ </bqbiol:is>\n+ </rdf:Description>\n+ </rdf:RDF>\n+ </annotation>\n+ </fbc:geneProduct>\n+ <fbc:geneProduct fbc:id="G_b2465" fbc:name="tktB" fbc:label="G_b2465"/>\n+ <fbc:geneProduct fbc:id="G_b3919" fbc:name="tpiA" fbc:label="G_b3919"/>\n+ </fbc:listOfGeneProducts>\n+ </model>\n+</sbml>\n' |
b |
diff -r 000000000000 -r b79cf44068bc test-data/textbook_model_cobrapy_exchange.csv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/textbook_model_cobrapy_exchange.csv Fri Dec 13 21:32:58 2024 +0000 |
b |
@@ -0,0 +1,21 @@ +reaction_id;reaction_name;reaction_stoichiometry;lower_bound;upper_bound +EX_ac_e;Acetate exchange;ac_e --> ;0.0;1000.0 +EX_acald_e;Acetaldehyde exchange;acald_e --> ;0.0;1000.0 +EX_akg_e;2-Oxoglutarate exchange;akg_e --> ;0.0;1000.0 +EX_co2_e;CO2 exchange;co2_e <=> ;-1000.0;1000.0 +EX_etoh_e;Ethanol exchange;etoh_e --> ;0.0;1000.0 +EX_for_e;Formate exchange;for_e --> ;0.0;1000.0 +EX_fru_e;D-Fructose exchange;fru_e --> ;0.0;1000.0 +EX_fum_e;Fumarate exchange;fum_e --> ;0.0;1000.0 +EX_glc__D_e;D-Glucose exchange;glc__D_e <=> ;-10.0;1000.0 +EX_gln__L_e;L-Glutamine exchange;gln__L_e --> ;0.0;1000.0 +EX_glu__L_e;L-Glutamate exchange;glu__L_e --> ;0.0;1000.0 +EX_h_e;H+ exchange;h_e <=> ;-1000.0;1000.0 +EX_h2o_e;H2O exchange;h2o_e <=> ;-1000.0;1000.0 +EX_lac__D_e;D-lactate exchange;lac__D_e --> ;0.0;1000.0 +EX_mal__L_e;L-Malate exchange;mal__L_e --> ;0.0;1000.0 +EX_nh4_e;Ammonia exchange;nh4_e <=> ;-1000.0;1000.0 +EX_o2_e;O2 exchange;o2_e <=> ;-1000.0;1000.0 +EX_pi_e;Phosphate exchange;pi_e <=> ;-1000.0;1000.0 +EX_pyr_e;Pyruvate exchange;pyr_e --> ;0.0;1000.0 +EX_succ_e;Succinate exchange;succ_e --> ;0.0;1000.0 |