| 491 | 1 """ | 
|  | 2 Convert a tabular (CSV/TSV/Tabular) description of a COBRA model into a COBRA file. | 
|  | 3 | 
|  | 4 Supported output formats: SBML, JSON, MATLAB (.mat), YAML. | 
|  | 5 The script logs to a user-provided file for easier debugging in Galaxy. | 
|  | 6 """ | 
|  | 7 | 
|  | 8 import os | 
|  | 9 import cobra | 
|  | 10 import argparse | 
|  | 11 from typing import List | 
|  | 12 import logging | 
|  | 13 import utils.model_utils as modelUtils | 
|  | 14 | 
|  | 15 ARGS : argparse.Namespace | 
|  | 16 def process_args(args: List[str] = None) -> argparse.Namespace: | 
|  | 17     """ | 
|  | 18     Parse command-line arguments for the CSV-to-COBRA conversion tool. | 
|  | 19 | 
|  | 20     Returns: | 
|  | 21         argparse.Namespace: Parsed arguments. | 
|  | 22     """ | 
|  | 23     parser = argparse.ArgumentParser( | 
|  | 24     usage="%(prog)s [options]", | 
|  | 25     description="Convert a tabular/CSV file to a COBRA model" | 
|  | 26     ) | 
|  | 27 | 
|  | 28 | 
|  | 29     parser.add_argument("--out_log", type=str, required=True, | 
|  | 30     help="Output log file") | 
|  | 31 | 
|  | 32 | 
|  | 33     parser.add_argument("--input", type=str, required=True, | 
|  | 34     help="Input tabular file (CSV/TSV)") | 
|  | 35 | 
|  | 36 | 
|  | 37     parser.add_argument("--format", type=str, required=True, choices=["sbml", "json", "mat", "yaml"], | 
|  | 38     help="Model format (SBML, JSON, MATLAB, YAML)") | 
|  | 39 | 
|  | 40 | 
|  | 41     parser.add_argument("--output", type=str, required=True, | 
|  | 42     help="Output model file path") | 
|  | 43 | 
|  | 44     parser.add_argument("--tool_dir", type=str, default=os.path.dirname(__file__), | 
|  | 45     help="Tool directory (passed from Galaxy as $__tool_directory__)") | 
|  | 46 | 
|  | 47 | 
|  | 48     return parser.parse_args(args) | 
|  | 49 | 
|  | 50 | 
|  | 51 ###############################- ENTRY POINT -################################ | 
|  | 52 | 
|  | 53 def main(args: List[str] = None) -> None: | 
|  | 54     """ | 
|  | 55     Entry point: parse arguments, build the COBRA model from a CSV/TSV file, | 
|  | 56     and save it in the requested format. | 
|  | 57 | 
|  | 58     Returns: | 
|  | 59         None | 
|  | 60     """ | 
|  | 61     global ARGS | 
|  | 62     ARGS = process_args(args) | 
|  | 63 | 
|  | 64     # configure logging to the requested log file (overwrite each run) | 
|  | 65     logging.basicConfig(filename=ARGS.out_log, | 
|  | 66                         level=logging.DEBUG, | 
|  | 67                         format='%(asctime)s %(levelname)s: %(message)s', | 
|  | 68                         filemode='w') | 
|  | 69 | 
|  | 70     logging.info('Starting fromCSVtoCOBRA tool') | 
|  | 71     logging.debug('Args: input=%s format=%s output=%s tool_dir=%s', ARGS.input, ARGS.format, ARGS.output, ARGS.tool_dir) | 
|  | 72 | 
|  | 73     try: | 
|  | 74         # Basic sanity checks | 
|  | 75         if not os.path.exists(ARGS.input): | 
|  | 76             logging.error('Input file not found: %s', ARGS.input) | 
|  | 77 | 
|  | 78         out_dir = os.path.dirname(os.path.abspath(ARGS.output)) | 
|  | 79 | 
|  | 80         if out_dir and not os.path.isdir(out_dir): | 
|  | 81             try: | 
|  | 82                 os.makedirs(out_dir, exist_ok=True) | 
|  | 83                 logging.info('Created missing output directory: %s', out_dir) | 
|  | 84             except Exception as e: | 
|  | 85                 logging.exception('Cannot create output directory: %s', out_dir) | 
|  | 86 | 
|  | 87         model = modelUtils.build_cobra_model_from_csv(ARGS.input) | 
| 498 | 88 | 
|  | 89 | 
|  | 90         logging.info('Created model with name: %s (ID: %s)', model.name, model.id) | 
| 491 | 91 | 
| 498 | 92         # Save model in requested format - Galaxy handles the filename | 
| 491 | 93         if ARGS.format == "sbml": | 
|  | 94             cobra.io.write_sbml_model(model, ARGS.output) | 
|  | 95         elif ARGS.format == "json": | 
|  | 96             cobra.io.save_json_model(model, ARGS.output) | 
|  | 97         elif ARGS.format == "mat": | 
|  | 98             cobra.io.save_matlab_model(model, ARGS.output) | 
|  | 99         elif ARGS.format == "yaml": | 
|  | 100             cobra.io.save_yaml_model(model, ARGS.output) | 
|  | 101         else: | 
|  | 102             logging.error('Unknown format requested: %s', ARGS.format) | 
| 498 | 103             raise ValueError(f"Unknown format: {ARGS.format}") | 
| 491 | 104 | 
|  | 105 | 
|  | 106         logging.info('Model successfully written to %s (format=%s)', ARGS.output, ARGS.format) | 
| 498 | 107         print(f"Model created successfully in {ARGS.format.upper()} format") | 
| 491 | 108 | 
| 498 | 109     except Exception as e: | 
| 491 | 110         # Log full traceback to the out_log so Galaxy users/admins can see what happened | 
|  | 111         logging.exception('Unhandled exception in fromCSVtoCOBRA') | 
| 498 | 112         print(f"ERROR: {str(e)}") | 
|  | 113         raise | 
| 491 | 114 | 
|  | 115 | 
|  | 116 if __name__ == '__main__': | 
|  | 117     main() |