Mercurial > repos > bimib > cobraxy
comparison COBRAxy/flux_simulation_beta.py @ 456:a6e45049c1b9 draft default tip
Uploaded
author | francesco_lapi |
---|---|
date | Fri, 12 Sep 2025 17:28:45 +0000 |
parents | f49c951c9fe6 |
children |
comparison
equal
deleted
inserted
replaced
455:4e2bc80764b6 | 456:a6e45049c1b9 |
---|---|
1 """ | |
2 Flux sampling and analysis utilities for COBRA models. | |
3 | |
4 This script supports two modes: | |
5 - Mode 1 (model_and_bounds=True): load a base model and apply bounds from | |
6 separate files before sampling. | |
7 - Mode 2 (model_and_bounds=False): load complete models and sample directly. | |
8 | |
9 Sampling algorithms supported: OPTGP and CBS. Outputs include flux samples | |
10 and optional analyses (pFBA, FVA, sensitivity), saved as tabular files. | |
11 """ | |
12 | |
1 import argparse | 13 import argparse |
2 import utils.general_utils as utils | 14 import utils.general_utils as utils |
3 from typing import Optional, List | 15 from typing import List |
4 import os | 16 import os |
5 import numpy as np | |
6 import pandas as pd | 17 import pandas as pd |
7 import cobra | 18 import cobra |
8 import utils.CBS_backend as CBS_backend | 19 import utils.CBS_backend as CBS_backend |
9 from joblib import Parallel, delayed, cpu_count | 20 from joblib import Parallel, delayed, cpu_count |
10 from cobra.sampling import OptGPSampler | 21 from cobra.sampling import OptGPSampler |
119 log.write(s + "\n\n") | 130 log.write(s + "\n\n") |
120 print(s) | 131 print(s) |
121 | 132 |
122 | 133 |
123 def write_to_file(dataset: pd.DataFrame, name: str, keep_index:bool=False)->None: | 134 def write_to_file(dataset: pd.DataFrame, name: str, keep_index:bool=False)->None: |
135 """ | |
136 Write a DataFrame to a TSV file under ARGS.output_path with a given base name. | |
137 | |
138 Args: | |
139 dataset: The DataFrame to write. | |
140 name: Base file name (without extension). | |
141 keep_index: Whether to keep the DataFrame index in the file. | |
142 | |
143 Returns: | |
144 None | |
145 """ | |
124 dataset.index.name = 'Reactions' | 146 dataset.index.name = 'Reactions' |
125 dataset.to_csv(ARGS.output_path + "/" + name + ".csv", sep = '\t', index = keep_index) | 147 dataset.to_csv(ARGS.output_path + "/" + name + ".csv", sep = '\t', index = keep_index) |
126 | 148 |
127 ############################ dataset input #################################### | 149 ############################ dataset input #################################### |
128 def read_dataset(data :str, name :str) -> pd.DataFrame: | 150 def read_dataset(data :str, name :str) -> pd.DataFrame: |
178 | 200 |
179 write_to_file(samplesTotal.T, model_name, True) | 201 write_to_file(samplesTotal.T, model_name, True) |
180 | 202 |
181 for i in range(0, n_batches): | 203 for i in range(0, n_batches): |
182 os.remove(ARGS.output_path + "/" + model_name + '_'+ str(i)+'_OPTGP.csv') | 204 os.remove(ARGS.output_path + "/" + model_name + '_'+ str(i)+'_OPTGP.csv') |
183 pass | |
184 | 205 |
185 | 206 |
186 def CBS_sampler(model:cobra.Model, model_name:str, n_samples:int=1000, n_batches:int=1, seed:int=0)-> None: | 207 def CBS_sampler(model:cobra.Model, model_name:str, n_samples:int=1000, n_batches:int=1, seed:int=0)-> None: |
187 """ | 208 """ |
188 Samples using the CBS (Constraint-based Sampling) algorithm and saves the results to CSV files. | 209 Samples using the CBS (Constraint-based Sampling) algorithm and saves the results to CSV files. |
222 | 243 |
223 write_to_file(samplesTotal.T, model_name, True) | 244 write_to_file(samplesTotal.T, model_name, True) |
224 | 245 |
225 for i in range(0, n_batches): | 246 for i in range(0, n_batches): |
226 os.remove(ARGS.output_path + "/" + model_name + '_'+ str(i)+'_CBS.csv') | 247 os.remove(ARGS.output_path + "/" + model_name + '_'+ str(i)+'_CBS.csv') |
227 pass | |
228 | 248 |
229 | 249 |
230 | 250 |
231 def model_sampler_with_bounds(model_input_original: cobra.Model, bounds_path: str, cell_name: str) -> List[pd.DataFrame]: | 251 def model_sampler_with_bounds(model_input_original: cobra.Model, bounds_path: str, cell_name: str) -> List[pd.DataFrame]: |
232 """ | 252 """ |
391 return df_pFBA, df_FVA, df_sensitivity | 411 return df_pFBA, df_FVA, df_sensitivity |
392 | 412 |
393 ############################# main ########################################### | 413 ############################# main ########################################### |
394 def main(args :List[str] = None) -> None: | 414 def main(args :List[str] = None) -> None: |
395 """ | 415 """ |
396 Initializes everything and sets the program in motion based on the fronted input arguments. | 416 Initialize and run sampling/analysis based on the frontend input arguments. |
397 | 417 |
398 Returns: | 418 Returns: |
399 None | 419 None |
400 """ | 420 """ |
401 | 421 |
404 global ARGS | 424 global ARGS |
405 ARGS = process_args(args) | 425 ARGS = process_args(args) |
406 | 426 |
407 if not os.path.exists(ARGS.output_path): | 427 if not os.path.exists(ARGS.output_path): |
408 os.makedirs(ARGS.output_path) | 428 os.makedirs(ARGS.output_path) |
409 | |
410 #ARGS.bounds = ARGS.input.split(",") | |
411 #ARGS.bounds_name = ARGS.name.split(",") | |
412 #ARGS.output_types = ARGS.output_type.split(",") | |
413 #ARGS.output_type_analysis = ARGS.output_type_analysis.split(",") | |
414 | 429 |
415 # --- Normalize inputs (the tool may pass comma-separated --input and either --name or --names) --- | 430 # --- Normalize inputs (the tool may pass comma-separated --input and either --name or --names) --- |
416 ARGS.input_files = ARGS.input.split(",") if ARGS.input else [] | 431 ARGS.input_files = ARGS.input.split(",") if ARGS.input else [] |
417 ARGS.file_names = ARGS.name.split(",") | 432 ARGS.file_names = ARGS.name.split(",") |
418 # output types (required) -> list | 433 # output types (required) -> list |
437 | 452 |
438 base_model = model_utils.build_cobra_model_from_csv(ARGS.model_upload) | 453 base_model = model_utils.build_cobra_model_from_csv(ARGS.model_upload) |
439 | 454 |
440 validation = model_utils.validate_model(base_model) | 455 validation = model_utils.validate_model(base_model) |
441 | 456 |
442 print("\n=== VALIDAZIONE MODELLO ===") | 457 print("\n=== MODEL VALIDATION ===") |
443 for key, value in validation.items(): | 458 for key, value in validation.items(): |
444 print(f"{key}: {value}") | 459 print(f"{key}: {value}") |
445 | 460 |
446 #Set solver verbosity to 1 to see warning and error messages only. | 461 # Set solver verbosity to 1 to see warning and error messages only. |
447 base_model.solver.configuration.verbosity = 1 | 462 base_model.solver.configuration.verbosity = 1 |
448 | 463 |
449 # Process each bounds file with the base model | 464 # Process each bounds file with the base model |
450 results = Parallel(n_jobs=num_processors)( | 465 results = Parallel(n_jobs=num_processors)( |
451 delayed(model_sampler_with_bounds)(base_model, bounds_file, cell_name) | 466 delayed(model_sampler_with_bounds)(base_model, bounds_file, cell_name) |
452 for bounds_file, cell_name in zip(ARGS.input_files, ARGS.file_names) | 467 for bounds_file, cell_name in zip(ARGS.input_files, ARGS.file_names) |
453 ) | 468 ) |
454 | 469 |
496 if("sensitivity" in ARGS.output_type_analysis): | 511 if("sensitivity" in ARGS.output_type_analysis): |
497 all_sensitivity = pd.concat([result[index_result] for result in results], ignore_index=False) | 512 all_sensitivity = pd.concat([result[index_result] for result in results], ignore_index=False) |
498 all_sensitivity = all_sensitivity.sort_index() | 513 all_sensitivity = all_sensitivity.sort_index() |
499 write_to_file(all_sensitivity.T, "sensitivity", True) | 514 write_to_file(all_sensitivity.T, "sensitivity", True) |
500 | 515 |
501 pass | 516 return |
502 | 517 |
503 ############################################################################## | 518 ############################################################################## |
504 if __name__ == "__main__": | 519 if __name__ == "__main__": |
505 main() | 520 main() |