Skip to content

Commit

Permalink
Merge pull request #1452 from Clinical-Genomics/release_v15.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Vadym authored Jun 26, 2024
2 parents 8c5e424 + 2f16974 commit ae2cf75
Show file tree
Hide file tree
Showing 8 changed files with 517 additions and 248 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ BALSAMIC_reference/
BALSAMIC/workflows/umi_workflow
BALSAMIC/workflows/umi_workflow/.*
.idea/
.vscode/
23 changes: 15 additions & 8 deletions BALSAMIC/commands/config/case.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Balsamic config case CLI."""

import logging
from datetime import datetime
from pathlib import Path
Expand Down Expand Up @@ -36,6 +37,7 @@
OPTION_SWEGEN_SV,
OPTION_TUMOR_SAMPLE_NAME,
OPTION_UMI,
OPTION_UMI_MIN_READS,
OPTION_UMI_TRIM_LENGTH,
)
from BALSAMIC.constants.analysis import BIOINFO_TOOL_ENV, AnalysisWorkflow, Gender
Expand Down Expand Up @@ -87,6 +89,7 @@
@OPTION_TUMOR_SAMPLE_NAME
@OPTION_UMI
@OPTION_UMI_TRIM_LENGTH
@OPTION_UMI_MIN_READS
@click.pass_context
def case_config(
context: click.Context,
Expand Down Expand Up @@ -119,6 +122,7 @@ def case_config(
tumor_sample_name: str,
umi: bool,
umi_trim_length: int,
umi_min_reads: str | None,
):
references_path: Path = Path(balsamic_cache, cache_version, genome_version)
references: Dict[str, Path] = get_absolute_paths_dict(
Expand Down Expand Up @@ -205,6 +209,7 @@ def case_config(
"analysis_workflow": analysis_workflow,
"config_creation_date": datetime.now().strftime("%Y-%m-%d %H:%M"),
},
custom_filters={"umi_min_reads": umi_min_reads if umi_min_reads else None},
reference=references,
singularity={
"image": Path(balsamic_cache, cache_version, "containers").as_posix()
Expand All @@ -221,14 +226,16 @@ def case_config(
bioinfo_tools=BIOINFO_TOOL_ENV,
container_conda_env_path=CONTAINERS_DIR,
),
panel={
"exome": exome,
"capture_kit": panel_bed,
"chrom": get_panel_chrom(panel_bed),
"pon_cnn": pon_cnn,
}
if panel_bed
else None,
panel=(
{
"exome": exome,
"capture_kit": panel_bed,
"chrom": get_panel_chrom(panel_bed),
"pon_cnn": pon_cnn,
}
if panel_bed
else None
),
).model_dump(by_alias=True, exclude_none=True)
LOG.info("Balsamic config model instantiated successfully")

Expand Down
14 changes: 13 additions & 1 deletion BALSAMIC/commands/options.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Balsamic command options."""

import click

from BALSAMIC import __version__ as balsamic_version
Expand All @@ -22,7 +23,11 @@
from BALSAMIC.constants.constants import LOG_LEVELS, LogLevel
from BALSAMIC.constants.rules import DELIVERY_RULES
from BALSAMIC.constants.workflow_params import VCF_DICT
from BALSAMIC.utils.cli import validate_cache_version, validate_exome_option
from BALSAMIC.utils.cli import (
validate_cache_version,
validate_exome_option,
validate_umi_min_reads,
)

OPTION_ADAPTER_TRIM = click.option(
"--adapter-trim/--no-adapter-trim",
Expand Down Expand Up @@ -423,3 +428,10 @@
type=click.INT,
help="Trim N bases from reads in FASTQ file",
)

OPTION_UMI_MIN_READS = click.option(
"--umi-min-reads",
type=click.STRING,
callback=validate_umi_min_reads,
help="Minimum raw reads supporting each UMI group. Format: 'x,y,z'.",
)
9 changes: 9 additions & 0 deletions BALSAMIC/models/config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Balsamic analysis config case models."""

import re
from glob import glob
from pathlib import Path
Expand Down Expand Up @@ -171,6 +172,12 @@ def validate_pon_version(cls, pon_version: Optional[str]):
return pon_version


class CustomFilters(BaseModel):
"""Variant calling custom filters."""

umi_min_reads: str | None = None


class ConfigModel(BaseModel):
"""
Class providing common functions and variables for different balsamic workflows.
Expand All @@ -186,6 +193,7 @@ class ConfigModel(BaseModel):
vcf : Field(VCFmodel); variables relevant for variant calling pipeline
background_variants: Field(Path(optional)); path to BACKGROUND VARIANTS for UMI
analysis: Field(AnalysisModel); Pydantic model containing workflow variables
custom_filters: Field(CustomFilters); custom parameters for variant filtering
This class also contains functions that help retrieve sample and file information,
facilitating BALSAMIC run operations in Snakemake.
Expand All @@ -211,6 +219,7 @@ class ConfigModel(BaseModel):
vcf: Optional[VCFModel] = None
background_variants: Optional[str] = None
analysis: AnalysisModel
custom_filters: CustomFilters | None = None

@field_validator("reference")
def abspath_as_str(cls, reference: Dict[str, Path]):
Expand Down
29 changes: 23 additions & 6 deletions BALSAMIC/utils/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,12 +296,16 @@ def get_fastq_info(sample_name: str, fastq_path: str) -> Dict[str, FastqInfoMode
"fwd": fwd_fastq,
"rev": rev_fastq,
}
fastq_dict[fastq_pair_pattern].update(
{
"fwd_resolved": Path(fwd_fastq).resolve().as_posix(),
"rev_resolved": Path(rev_fastq).resolve().as_posix(),
}
) if Path(fwd_fastq).is_symlink() or Path(rev_fastq).is_symlink() else None
(
fastq_dict[fastq_pair_pattern].update(
{
"fwd_resolved": Path(fwd_fastq).resolve().as_posix(),
"rev_resolved": Path(rev_fastq).resolve().as_posix(),
}
)
if Path(fwd_fastq).is_symlink() or Path(rev_fastq).is_symlink()
else None
)

if not fastq_dict:
error_message = f"No fastqs found for: {sample_name} in {fastq_path}"
Expand Down Expand Up @@ -511,3 +515,16 @@ def validate_cache_version(
raise click.BadParameter(
f"Invalid cache version format. Use '{CacheVersion.DEVELOP}' or 'X.X.X'."
)


def validate_umi_min_reads(
_ctx: click.Context, _param: click.Parameter, umi_min_reads: str | None
) -> str:
"""Validate the provided cache version."""
if umi_min_reads:
umi_min_reads_parts: List[str] = umi_min_reads.split(",")
if len(umi_min_reads_parts) == 3 and all(
part.isdigit() for part in umi_min_reads_parts
):
return umi_min_reads
raise click.BadParameter("Invalid UMI minimum reads format. Use 'x,y,z'.")
Loading

0 comments on commit ae2cf75

Please sign in to comment.