Skip to content

Commit 78fda57

Browse files
authored
Merge pull request #6 from cdbope/master
update readme
2 parents 978e153 + 58c434b commit 78fda57

6 files changed

Lines changed: 84 additions & 56 deletions

File tree

example_data/COSMICv34_cns.txt

Lines changed: 20 additions & 0 deletions
Large diffs are not rendered by default.

example_data/small_genome.fa

Lines changed: 0 additions & 43 deletions
This file was deleted.
4.54 KB
Binary file not shown.

requirements_dev.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@ hypothesis
1111
coverage
1212
pytest-cov
1313
build
14-
1514
numpy
1615
scipy
1716
pandas
1817
bionumpy
1918
setuptools
20-
2119
seaborn
2220
matplotlib
21+
typing_extensions
22+
requests
23+
scikit-learn

setup.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
'scikit-learn',
1818
'bionumpy',
1919
'matplotlib',
20-
'seaborn']
20+
'seaborn',
21+
'typing_extensions',
22+
'requests']
2123

2224
test_requirements = ['pytest>=3', "hypothesis"]
2325

starsigndna/cli.py

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -348,17 +348,33 @@ def refit(matrix_file: Annotated[str, typer.Argument(help='Tab separated matrix
348348
start_time = time.time()
349349
file_name, file_extension = os.path.splitext(matrix_file)
350350

351-
# Handle VCF input
352-
if file_extension == '.vcf':
351+
# Handle VCF input (both .vcf and .vcf.gz)
352+
if file_extension == '.vcf' or (file_extension == '.gz' and os.path.splitext(file_name)[1] == '.vcf'):
353353
if not ref_genome and not genome_path:
354354
raise ValueError("Either ref_genome or genome_path must be provided.")
355355
genome_path = download_reference_genome(ref_genome=ref_genome, genome_path=genome_path)
356356
logger.info(f"Reference genome path: {genome_path}")
357-
count_mutation(matrix_file, genome_path, f'{output_folder}/matrix.csv', numeric_chromosomes, genotyped)
358-
matrix_file = f'{output_folder}/matrix.csv'
357+
# Derive output csv path from input sample name
358+
sample_name = Path(matrix_file).name
359+
if sample_name.endswith('.vcf.gz'):
360+
sample_name = sample_name[:-7]
361+
elif sample_name.endswith('.vcf'):
362+
sample_name = sample_name[:-4]
363+
out_csv = f"{output_folder}/{sample_name}.csv"
364+
os.makedirs(output_folder, exist_ok=True)
365+
count_mutation(matrix_file, genome_path, out_csv, numeric_chromosomes, genotyped)
366+
matrix_file = out_csv
359367

360368
# Read input data
361369
M = read_counts(matrix_file)
370+
371+
# Remove rows with all zeros (can occur with genotyped VCFs)
372+
row_sums = M.sum(axis=1)
373+
if (row_sums == 0).any():
374+
n_zero_rows = (row_sums == 0).sum()
375+
logger.warning(f"Removing {n_zero_rows} empty row(s) with zero mutation counts from the matrix")
376+
M = M[row_sums > 0]
377+
362378
index_matrix = M.index.values.tolist()
363379
S = read_signature(signature_file)
364380

@@ -376,7 +392,23 @@ def refit(matrix_file: Annotated[str, typer.Argument(help='Tab separated matrix
376392
S = signatures
377393

378394
if signature_names is not None:
379-
S = filter_signatures(S, signature_names.split(','))
395+
requested_sigs = signature_names.split(',')
396+
# Only keep signatures that are both requested and available after filtering
397+
available_requested = [sig for sig in requested_sigs if sig in S.index]
398+
399+
if len(available_requested) < 5:
400+
missing_sigs = [sig for sig in requested_sigs if sig not in S.index]
401+
logger.warning(f"Only {len(available_requested)} of the requested signatures are available after correlation filtering.")
402+
logger.warning(f"Missing signatures: {', '.join(missing_sigs)}")
403+
logger.warning(f"Available signatures: {', '.join(S.index.tolist())}")
404+
raise ValueError(f"Only {len(available_requested)} requested signatures are available after filtering. At least 5 are required. Missing: {missing_sigs}")
405+
406+
if len(available_requested) < len(requested_sigs):
407+
missing_sigs = [sig for sig in requested_sigs if sig not in S.index]
408+
logger.warning(f"Some requested signatures were filtered out due to low correlation with the sample: {', '.join(missing_sigs)}")
409+
logger.info(f"Using {len(available_requested)} available signatures: {', '.join(available_requested)}")
410+
411+
S = filter_signatures(S, available_requested)
380412

381413
# Prepare data for analysis
382414
index_signature = S.index.values.tolist()
@@ -496,7 +528,7 @@ def get_lambda(data_type: DataType) -> float:
496528
Returns:
497529
float: Lambda value for regularization
498530
"""
499-
return 100 if data_type == DataType.genome else 0.7
531+
return 1000 if data_type == DataType.genome else 0.7
500532

501533

502534
def read_opportunity(M: np.ndarray, opportunity_file: Optional[str] = None) -> np.ndarray:
@@ -614,17 +646,33 @@ def denovo(matrix_file: Annotated[str, typer.Argument(help='Tab separated matrix
614646
logger.info(f'Starting de novo analysis for {run_name}')
615647
start_time = time.time()
616648

617-
# Handle VCF input
618-
if matrix_file.endswith('.vcf'):
649+
# Handle VCF input (both .vcf and .vcf.gz)
650+
if matrix_file.endswith('.vcf') or matrix_file.endswith('.vcf.gz'):
619651
if not ref_genome and not genome_path:
620652
raise ValueError("Either ref_genome or genome_path must be provided.")
621653
genome_path = download_reference_genome(ref_genome=ref_genome, genome_path=genome_path)
622654
logger.info(f"Reference genome path: {genome_path}")
623-
count_mutation(matrix_file, genome_path, f'{output_folder}/matrix.csv', numeric_chromosomes, genotyped)
624-
matrix_file = f'{output_folder}/matrix.csv'
655+
# Derive output csv path from input sample name
656+
sample_name = Path(matrix_file).name
657+
if sample_name.endswith('.vcf.gz'):
658+
sample_name = sample_name[:-7]
659+
elif sample_name.endswith('.vcf'):
660+
sample_name = sample_name[:-4]
661+
out_csv = f"{output_folder}/{sample_name}.csv"
662+
os.makedirs(output_folder, exist_ok=True)
663+
count_mutation(matrix_file, genome_path, out_csv, numeric_chromosomes, genotyped)
664+
matrix_file = out_csv
625665

626666
# Read and prepare data
627667
M = read_counts(matrix_file)
668+
669+
# Remove rows with all zeros (can occur with genotyped VCFs)
670+
row_sums = M.sum(axis=1)
671+
if (row_sums == 0).any():
672+
n_zero_rows = (row_sums == 0).sum()
673+
logger.warning(f"Removing {n_zero_rows} empty row(s) with zero mutation counts from the matrix")
674+
M = M[row_sums > 0]
675+
628676
index_matrix = M.index.values.tolist()
629677
desired_order = M.columns
630678
O = read_opportunity(M, opportunity_file)

0 commit comments

Comments
 (0)