From 3ca0a76abfb12247ac852304f8c9a79e13e6890e Mon Sep 17 00:00:00 2001 From: gp201 Date: Thu, 12 Jun 2025 22:21:05 -0700 Subject: [PATCH 1/4] feat: add debug flag to process_and_reroot_lineages function and update related tests --- barcodeforge/cli.py | 1 + barcodeforge/ref_muts.py | 6 ++++++ tests/test_cli.py | 19 +++++++++++-------- tests/test_ref_muts.py | 4 ++++ 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/barcodeforge/cli.py b/barcodeforge/cli.py index 4ff7d12..aecd12b 100644 --- a/barcodeforge/cli.py +++ b/barcodeforge/cli.py @@ -236,6 +236,7 @@ def barcode( ) process_and_reroot_lineages( + debug=is_debug, sample_muts_path=os.path.join(intermediate_dir, "samplePaths.txt"), reference_fasta_path=reference_genome, sequences_fasta_path=alignment, diff --git a/barcodeforge/ref_muts.py b/barcodeforge/ref_muts.py index 3d9ce9f..ad8912a 100755 --- a/barcodeforge/ref_muts.py +++ b/barcodeforge/ref_muts.py @@ -117,6 +117,7 @@ def _sanitize_mutation_data(mutations): def process_and_reroot_lineages( + debug: bool, sample_muts_path: str, reference_fasta_path: str, sequences_fasta_path: str, @@ -146,6 +147,11 @@ def process_and_reroot_lineages( for i in additional_muts.keys(): additional_muts[i]["ref"] = additional_muts[i].pop("base") additional_muts[i]["root"] = additional_muts[i].pop("mut") + + if debug: + console.print( + f"[{STYLES['debug']}]Additional mutations derived from reference {ref.id}: {additional_muts}[/{STYLES['debug']}]" + ) # else generate the root sequence else: console.print( diff --git a/tests/test_cli.py b/tests/test_cli.py index 51b09d6..c96545e 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -193,6 +193,7 @@ def test_barcode_command_default_options(runner, temp_files, mocker): mock_run_subp.assert_has_calls(expected_subprocess_calls, any_order=False) mock_process_reroot.assert_called_once_with( + debug=False, sample_muts_path=matutils_S_output_fn, reference_fasta_path=temp_files["ref_genome"], sequences_fasta_path=temp_files["alignment"], @@ -207,9 +208,9 @@ def test_barcode_command_default_options(runner, temp_files, mocker): prefix="", # Default prefix "" ) mock_create_plot.assert_called_once_with( - debug=False, # Add the debug argument + debug=False, input_file_path=final_barcodes_csv_fn, - chunk_size=100, # Add chunk_size, default from CLI is 100 + chunk_size=100, output_file_path=final_barcode_plot_fn, ) @@ -349,6 +350,7 @@ def test_barcode_command_custom_options(runner, temp_files, mocker): mock_run_subp.assert_has_calls(expected_subprocess_calls, any_order=False) mock_process_reroot.assert_called_once_with( + debug=False, sample_muts_path=matutils_S_output_fn, reference_fasta_path=temp_files["ref_genome"], sequences_fasta_path=temp_files["alignment"], @@ -357,15 +359,15 @@ def test_barcode_command_custom_options(runner, temp_files, mocker): output_rerooted_lineage_paths_path=rerooted_lineage_paths_fn, ) mock_create_barcodes.assert_called_once_with( - debug=False, # Add the debug argument + debug=False, input_file_path=rerooted_lineage_paths_fn, output_file_path=final_barcodes_csv_fn, prefix=prefix, ) mock_create_plot.assert_called_once_with( - debug=False, # Add the debug argument + debug=False, input_file_path=final_barcodes_csv_fn, - chunk_size=100, # Add chunk_size, default from CLI is 100 unless specified + chunk_size=100, output_file_path=final_barcode_plot_fn, ) @@ -511,6 +513,7 @@ def test_barcode_command_debug_flag(runner, temp_files, mocker): ) mock_process_reroot.assert_called_once_with( + debug=True, sample_muts_path=matutils_S_output_fn, reference_fasta_path=temp_files["ref_genome"], sequences_fasta_path=temp_files["alignment"], @@ -522,12 +525,12 @@ def test_barcode_command_debug_flag(runner, temp_files, mocker): debug=True, input_file_path=rerooted_lineage_paths_fn, output_file_path=final_barcodes_csv_fn, - prefix="", # Default prefix "" + prefix="", ) mock_create_plot.assert_called_once_with( - debug=True, # Add the debug argument, should be True here + debug=True, input_file_path=final_barcodes_csv_fn, - chunk_size=100, # Add chunk_size, default from CLI is 100 + chunk_size=100, output_file_path=final_barcode_plot_fn, ) diff --git a/tests/test_ref_muts.py b/tests/test_ref_muts.py index ac81608..43a97a5 100644 --- a/tests/test_ref_muts.py +++ b/tests/test_ref_muts.py @@ -195,6 +195,7 @@ def test_process_and_reroot_lineages_ref_present( output_rerooted_lineages = tmp_path / "rerooted_lineages.tsv" process_and_reroot_lineages( + debug=False, sample_muts_path=str(muts_file_ref_present), reference_fasta_path=sample_ref_fasta_file, sequences_fasta_path=sample_seqs_fasta_file, # sampleA is in here @@ -265,6 +266,7 @@ def test_process_and_reroot_lineages_ref_not_in_muts_infer_root( mocker.patch("barcodeforge.ref_muts.console", mocked_console) process_and_reroot_lineages( + debug=False, sample_muts_path=str(muts_file), reference_fasta_path=sample_ref_fasta_file, # ref_genome AAAAAAAAAA sequences_fasta_path=str(seqs_file), @@ -349,6 +351,7 @@ def test_process_and_reroot_lineages_value_error_empty_root_seqs( match="No valid root sequences could be generated. Check input FASTA and sample mutations.", ): process_and_reroot_lineages( + debug=False, sample_muts_path=str(muts_file), reference_fasta_path=sample_ref_fasta_file, sequences_fasta_path=str(seqs_file), @@ -385,6 +388,7 @@ def test_process_and_reroot_lineages_warning_missing_sample_in_fasta( # Additional muts (ref vs inferred): none # Rerooted paths: original process_and_reroot_lineages( + debug=False, sample_muts_path=str(muts_file), reference_fasta_path=sample_ref_fasta_file, sequences_fasta_path=str(seqs_file), From 9e6152e037d69abc35fb9b7e02e32e14d66cfef4 Mon Sep 17 00:00:00 2001 From: gp201 Date: Thu, 12 Jun 2025 22:21:38 -0700 Subject: [PATCH 2/4] feat: update version to 1.1.1 in __init__.py and pyproject.toml --- barcodeforge/__init__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/barcodeforge/__init__.py b/barcodeforge/__init__.py index 5becc17..a82b376 100644 --- a/barcodeforge/__init__.py +++ b/barcodeforge/__init__.py @@ -1 +1 @@ -__version__ = "1.0.0" +__version__ = "1.1.1" diff --git a/pyproject.toml b/pyproject.toml index 4a732fd..b794858 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "BarcodeForge" -version = "1.0.0" +version = "1.1.1" description = "A CLI tool for generating pathogen-specific barcodes for Freyja." readme = "README.md" requires-python = ">=3.10" From a9e07188fa649b62fba892fd91e31f08afd63ce8 Mon Sep 17 00:00:00 2001 From: gp201 Date: Thu, 12 Jun 2025 22:45:39 -0700 Subject: [PATCH 3/4] fix: standardize command-line option for tree format to use hyphenated style --- barcodeforge/cli.py | 2 +- barcodeforge/utils.py | 2 +- tests/test_cli.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/barcodeforge/cli.py b/barcodeforge/cli.py index aecd12b..38e91a7 100644 --- a/barcodeforge/cli.py +++ b/barcodeforge/cli.py @@ -34,7 +34,7 @@ def cli(ctx, debug): @click.argument("tree", type=click.Path(exists=True, readable=True)) @click.argument("lineages", type=click.Path(exists=True, readable=True)) @click.option( - "--tree_format", + "--tree-format", type=click.Choice(["newick", "nexus"], case_sensitive=False), help="Specify the format of the tree file (newick or nexus)", ) diff --git a/barcodeforge/utils.py b/barcodeforge/utils.py index 5639529..31305ca 100644 --- a/barcodeforge/utils.py +++ b/barcodeforge/utils.py @@ -43,7 +43,7 @@ def resolve_tree_format( f"[{STYLES['error']}]Error: Unknown tree format for file '{tree_path}'. Extension '{ext}' is not recognized.[/{STYLES['error']}]" ) console.print( - f"[{STYLES['error']}]Please specify the format using --tree_format ('newick' or 'nexus').[/]" + f"[{STYLES['error']}]Please specify the format using --tree-format ('newick' or 'nexus').[/]" ) raise click.Abort() diff --git a/tests/test_cli.py b/tests/test_cli.py index c96545e..6e68c57 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -391,7 +391,7 @@ def test_barcode_command_nexus_tree(runner, temp_files, mocker): temp_files["alignment"], temp_files["tree"], temp_files["lineages"], - "--tree_format", + "--tree-format", "nexus", ] result = runner.invoke(cli, args, catch_exceptions=False) @@ -448,7 +448,7 @@ def test_barcode_command_newick_tree_reformat(runner, temp_files, mocker): temp_files["alignment"], temp_files["tree"], temp_files["lineages"], - "--tree_format", + "--tree-format", "newick", ] result = runner.invoke(cli, args, catch_exceptions=False) From 16cdc6f9599862d2a07027d0333eddf528cc25c1 Mon Sep 17 00:00:00 2001 From: gp201 Date: Thu, 12 Jun 2025 22:46:51 -0700 Subject: [PATCH 4/4] fix: undo previous commit that was not needed --- barcodeforge/cli.py | 2 +- barcodeforge/utils.py | 2 +- tests/test_cli.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/barcodeforge/cli.py b/barcodeforge/cli.py index 38e91a7..aecd12b 100644 --- a/barcodeforge/cli.py +++ b/barcodeforge/cli.py @@ -34,7 +34,7 @@ def cli(ctx, debug): @click.argument("tree", type=click.Path(exists=True, readable=True)) @click.argument("lineages", type=click.Path(exists=True, readable=True)) @click.option( - "--tree-format", + "--tree_format", type=click.Choice(["newick", "nexus"], case_sensitive=False), help="Specify the format of the tree file (newick or nexus)", ) diff --git a/barcodeforge/utils.py b/barcodeforge/utils.py index 31305ca..5639529 100644 --- a/barcodeforge/utils.py +++ b/barcodeforge/utils.py @@ -43,7 +43,7 @@ def resolve_tree_format( f"[{STYLES['error']}]Error: Unknown tree format for file '{tree_path}'. Extension '{ext}' is not recognized.[/{STYLES['error']}]" ) console.print( - f"[{STYLES['error']}]Please specify the format using --tree-format ('newick' or 'nexus').[/]" + f"[{STYLES['error']}]Please specify the format using --tree_format ('newick' or 'nexus').[/]" ) raise click.Abort() diff --git a/tests/test_cli.py b/tests/test_cli.py index 6e68c57..c96545e 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -391,7 +391,7 @@ def test_barcode_command_nexus_tree(runner, temp_files, mocker): temp_files["alignment"], temp_files["tree"], temp_files["lineages"], - "--tree-format", + "--tree_format", "nexus", ] result = runner.invoke(cli, args, catch_exceptions=False) @@ -448,7 +448,7 @@ def test_barcode_command_newick_tree_reformat(runner, temp_files, mocker): temp_files["alignment"], temp_files["tree"], temp_files["lineages"], - "--tree-format", + "--tree_format", "newick", ] result = runner.invoke(cli, args, catch_exceptions=False)