Mercurial > repos > iuc > gem_extract_exchange
comparison gem_knockout.py @ 0:d9893d41dd6a draft default tip
planemo upload for repository https://github.com/AlmaasLab/elixir-galaxy-tools-systemsbiology commit 3f7bec1264a86e1488ee1315dbac0f44675f5171
| author | iuc |
|---|---|
| date | Fri, 13 Dec 2024 21:33:34 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:d9893d41dd6a |
|---|---|
| 1 import argparse | |
| 2 | |
| 3 import cobra | |
| 4 import pandas as pd | |
| 5 | |
| 6 | |
| 7 def __main__(): | |
| 8 parser = argparse.ArgumentParser( | |
| 9 prog="FluxDistribution", | |
| 10 description="Performs FBA knockout analysis on a GEM.", | |
| 11 epilog="Adding an epilog, but doubt it's needed.", | |
| 12 ) | |
| 13 parser.add_argument( | |
| 14 "-m", | |
| 15 "--cb_model_location", | |
| 16 dest="cb_model_location", | |
| 17 action="store", | |
| 18 type=str, | |
| 19 default=None, | |
| 20 required=True, | |
| 21 help="The model to use." | |
| 22 ) | |
| 23 parser.add_argument( | |
| 24 "-output", | |
| 25 "--output", | |
| 26 dest="out_file", | |
| 27 action="store", | |
| 28 type=str, | |
| 29 default=None, | |
| 30 required=True, | |
| 31 help="The output file." | |
| 32 ) | |
| 33 parser.add_argument( | |
| 34 "-k", | |
| 35 "--knockout_type", | |
| 36 dest="knockout_type", | |
| 37 action="store", | |
| 38 type=str, | |
| 39 default="single", | |
| 40 required=False, | |
| 41 help="Type of knockout to perform, single or double" | |
| 42 ) | |
| 43 parser.add_argument( | |
| 44 "-g", | |
| 45 "--gene_knockouts", | |
| 46 dest="gene_knockouts", | |
| 47 action="store", | |
| 48 type=str, default=None, | |
| 49 required=False, | |
| 50 help="List of genes to knock out. Defaults to all." | |
| 51 ) | |
| 52 parser.add_argument( | |
| 53 "-u", | |
| 54 "--uptake_constraints_file", | |
| 55 dest="uptake_constraints_file", | |
| 56 action="store", | |
| 57 type=str, | |
| 58 default=None, | |
| 59 required=False, | |
| 60 help="File containing new uptake constraits." | |
| 61 ) | |
| 62 | |
| 63 args = parser.parse_args() | |
| 64 | |
| 65 # Reading the model | |
| 66 try: | |
| 67 cb_model = cobra.io.read_sbml_model(args.cb_model_location) | |
| 68 except Exception as e: | |
| 69 raise Exception( | |
| 70 "The model could not be read. " | |
| 71 "Ensure it is in correct SBML format." | |
| 72 ) from e | |
| 73 | |
| 74 # Verifying the genes are present in the model | |
| 75 gene_ids = [gene.id for gene in cb_model.genes] | |
| 76 | |
| 77 genes_to_knockout_1 = args.gene_knockouts.split(',')\ | |
| 78 if args.gene_knockouts is not None else [] | |
| 79 gene_bool = [ | |
| 80 True if gene in gene_ids else False for gene in genes_to_knockout_1 | |
| 81 ] | |
| 82 if not all(gene_bool): | |
| 83 print( | |
| 84 f'Found {sum(gene_bool)} of {len(genes_to_knockout_1)} genes ' | |
| 85 'in the model.' | |
| 86 ) | |
| 87 raise Exception( | |
| 88 "One or more of the genes to knockout are not present " | |
| 89 "in the model." | |
| 90 ) | |
| 91 | |
| 92 # Adding all genes to knockout if none are specified | |
| 93 if genes_to_knockout_1 is None or len(genes_to_knockout_1) == 0: | |
| 94 genes_to_knockout_1 = [gene.id for gene in cb_model.genes] | |
| 95 # Applying uptake constraints | |
| 96 if (args.uptake_constraints_file is not None | |
| 97 and args.uptake_constraints_file != "None"): | |
| 98 constraints_df = pd.read_csv( | |
| 99 args.uptake_constraints_file, | |
| 100 sep=";", | |
| 101 header=0, | |
| 102 index_col=False | |
| 103 ) | |
| 104 for index, row in constraints_df.iterrows(): | |
| 105 reaction = cb_model.reactions.get_by_id(row["reaction_id"]) | |
| 106 reaction.lower_bound = row["lower_bound"] | |
| 107 reaction.upper_bound = row["upper_bound"] | |
| 108 | |
| 109 result = pd.DataFrame(columns=[ | |
| 110 "reaction_id", "ko_gene_id_1", "ko_gene_id_2", | |
| 111 "reaction", "wildtype_flux", "knockout_flux" | |
| 112 ]) | |
| 113 | |
| 114 if args.knockout_type == "single": | |
| 115 genes_to_knockout_2 = [0] | |
| 116 elif args.knockout_type == "double": | |
| 117 genes_to_knockout_2 = genes_to_knockout_1.copy() | |
| 118 else: | |
| 119 raise Exception( | |
| 120 f"Invalid knockout type {args.knockout_type}. " | |
| 121 "Only single and double are allowed." | |
| 122 ) | |
| 123 | |
| 124 # Wildtype pFBA | |
| 125 with cb_model as model: | |
| 126 wildtype_solution = model.optimize() | |
| 127 | |
| 128 # Performing gene knockouts | |
| 129 for gene1 in genes_to_knockout_1: | |
| 130 for gene2 in genes_to_knockout_2: | |
| 131 with cb_model as model: | |
| 132 model.genes.get_by_id(gene1).knock_out() | |
| 133 if args.knockout_type == "double": | |
| 134 model.genes.get_by_id(gene2).knock_out() | |
| 135 solution = model.optimize() | |
| 136 for reaction in model.reactions: | |
| 137 result = pd.concat([result, pd.DataFrame([{ | |
| 138 "reaction_id": reaction.id, | |
| 139 "ko_gene_id_1": gene1, | |
| 140 "ko_gene_id_2": gene2 | |
| 141 if args.knockout_type == "double" else None, | |
| 142 "reaction": reaction.reaction, | |
| 143 "wildtype_flux": wildtype_solution.fluxes[reaction.id], | |
| 144 "knockout_flux": solution.fluxes[reaction.id], | |
| 145 }])], ignore_index=True) | |
| 146 | |
| 147 # Writing the results to file | |
| 148 result.to_csv(args.out_file, sep=";", index=False) | |
| 149 | |
| 150 | |
| 151 if __name__ == "__main__": | |
| 152 __main__() |
