Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update dev from patches #131

Merged
merged 22 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
487fa66
Update README.md
ravibandaru-lab Dec 9, 2024
879ed61
Merge pull request #119 from epifluidlab/ravibandaru-lab-patch-1
ravibandaru-lab Dec 9, 2024
3e5ba4e
Merge pull request #121 from epifluidlab/develop
ravibandaru-lab Dec 10, 2024
701c142
Merge pull request #122 from epifluidlab/develop
ravibandaru-lab Dec 16, 2024
574f6f7
Merge pull request #123 from epifluidlab/develop
jamesli124 Dec 18, 2024
9451c97
Update README.md
ravibandaru-lab Dec 18, 2024
4388de0
Merge pull request #124 from epifluidlab/ravibandaru-lab-patch-1
jamesli124 Dec 18, 2024
942a3bd
Merge pull request #127 from epifluidlab/develop
ravibandaru-lab Dec 19, 2024
3d2d77c
Update version.py
jamesli124 Dec 19, 2024
ecba3bd
Merge pull request #128 from epifluidlab/jamesli124-patch-1
ravibandaru-lab Dec 19, 2024
5b2d96d
add missing arg
jamesli124 Dec 19, 2024
790b2ff
update changelog
jamesli124 Dec 19, 2024
b263594
fix incorrect value error
jamesli124 Dec 19, 2024
0563635
Merge pull request #129 from epifluidlab/patch-missing-arg
ravibandaru-lab Dec 19, 2024
a96ac97
absolute imports
jamesli124 Dec 19, 2024
ffb02bd
fix incorrect function name for wps
jamesli124 Dec 19, 2024
b9d471e
update changelog
jamesli124 Dec 19, 2024
60b1e5f
add pytest warning assertion
jamesli124 Dec 19, 2024
172abf7
fix assertion
jamesli124 Dec 19, 2024
4a5af7c
Tests check if CLI properly imports modules and references a callable…
jamesli124 Dec 19, 2024
b4be59f
update changelog
jamesli124 Dec 19, 2024
03ea6d3
Merge pull request #130 from epifluidlab/fix-wps-cli
ravibandaru-lab Dec 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ The format is based on
and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.10.1] - 2024-12-19

### Fixed
- Added missing `-n` arg to `end-motifs`.
- Fixed incorrect `ValueError` regarding the `negative_strand` arg.
- Incorrect function name for `wps` leading to errors when called from CLI.

### Added
- Additional tests for the CLI lazy loading implementation

## [0.10.0] - 2024-12-18

### Changed
Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<ul>
<li><a href="#functionality">Functionality</a></li>
<li><a href="#documentation">Documentation</a></li>
<li><a href="#wiki">Wiki/Tutorials</a></li>
<li><a href="#compatible-file-formats">Compatible File Formats</a></li>
<li><a href="#using-fragment-files">Using Fragment Files</a></li>
</ul>
Expand Down Expand Up @@ -53,12 +54,14 @@ FinaleToolkit has support for the following cell-free DNA fragmentation features
### Documentation
Documentation for FinaleToolkit can be found [here](https://epifluidlab.github.io/finaletoolkit-docs/).

### Wiki/Tutorials
The wiki and tutorial page for FinaleToolkit can be found [here](https://github.com/epifluidlab/FinaleToolkit/wiki).

### Compatible File Formats

FinaleToolkit is compatible with almost any paired-end sequence data:

- Binary Alignment Map (`.bam`) files with an associated index file (`.bam.bai`).
- Sequence Alignment Map (`.sam`) files.
- Compressed Reference-oriented Alignment Map (`.cram`) files.
- Fragment (`.frag.gz`) files with an associated tabix index file (`.frag.gz.tbi`).

Expand All @@ -74,4 +77,4 @@ We encourage you to use our comprehensive database, FinaleDB, to access relevant
- Yaping Liu: yaping@northwestern.edu

## License
This project falls under an MIT license. See the included `LICENSE` file for details.
This project falls under an MIT license. See the included `LICENSE` file for details.
39 changes: 23 additions & 16 deletions src/finaletoolkit/cli/main_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def main_cli_parser():
action='store_true',
help='Enable verbose mode to display detailed processing information.')
cli_coverage.set_defaults(
module='..frag._coverage', func='coverage')
module='finaletoolkit.frag._coverage', func='coverage')

# frag-length-bins
cli_frag_length_bins = subparsers.add_parser(
Expand Down Expand Up @@ -186,7 +186,7 @@ def main_cli_parser():
default=0,
help='Enable verbose mode to display detailed processing '
'information.')
cli_frag_length_bins.set_defaults(module='..frag._frag_length', func='frag_length_bins')
cli_frag_length_bins.set_defaults(module='finaletoolkit.frag._frag_length', func='frag_length_bins')

# frag-length-intervals
cli_frag_length_intervals = subparsers.add_parser(
Expand Down Expand Up @@ -250,7 +250,7 @@ def main_cli_parser():
action='count',
help='Enable verbose mode to display detailed processing '
'information.')
cli_frag_length_intervals.set_defaults(module='..frag._frag_length', func='frag_length_intervals')
cli_frag_length_intervals.set_defaults(module='finaletoolkit.frag._frag_length', func='frag_length_intervals')

# cleavage-profile
cli_cleavage_profile = subparsers.add_parser(
Expand Down Expand Up @@ -337,7 +337,7 @@ def main_cli_parser():
default=0,
action='count',
help='Enable verbose mode to display detailed processing information.')
cli_cleavage_profile.set_defaults(module='..frag._cleavage_profile', func='multi_cleavage_profile')
cli_cleavage_profile.set_defaults(module='finaletoolkit.frag._cleavage_profile', func='multi_cleavage_profile')

# wps
cli_wps = subparsers.add_parser(
Expand Down Expand Up @@ -426,7 +426,7 @@ def main_cli_parser():
action='count',
default=0,
help='Enable verbose mode to display detailed processing information.')
cli_wps.set_defaults(module='..frag', func='_multi_wps')
cli_wps.set_defaults(module='finaletoolkit.frag', func='multi_wps')

# adjust wps
cli_adjust_wps = subparsers.add_parser(
Expand Down Expand Up @@ -508,7 +508,7 @@ def main_cli_parser():
'--verbose',
action='count',
help='Enable verbose mode to display detailed processing information.')
cli_adjust_wps.set_defaults(module='..frag._adjust_wps', func='adjust_wps')
cli_adjust_wps.set_defaults(module='finaletoolkit.frag._adjust_wps', func='adjust_wps')

# delfi
cli_delfi = subparsers.add_parser(
Expand Down Expand Up @@ -599,7 +599,7 @@ def main_cli_parser():
action='count',
default=0,
help='Enable verbose mode to display detailed processing information.')
cli_delfi.set_defaults(module='..frag._delfi', func='delfi')
cli_delfi.set_defaults(module='finaletoolkit.frag._delfi', func='delfi')

# delfi-gc-correct
cli_delfi_gc = subparsers.add_parser(
Expand Down Expand Up @@ -630,7 +630,7 @@ def main_cli_parser():
'--verbose',
action='count',
help='Enable verbose mode to display detailed processing information.')
cli_delfi_gc.set_defaults(module='..frag._delfi_gc_correct', func='cli_delfi_gc_correct')
cli_delfi_gc.set_defaults(module='finaletoolkit.frag._delfi_gc_correct', func='cli_delfi_gc_correct')

# end-motifs
cli_motifs = subparsers.add_parser(
Expand Down Expand Up @@ -670,6 +670,13 @@ def main_cli_parser():
dest="both_strands",
help="Set flag to only consider one strand for end-motifs."
)
cli_motifs.add_argument(
'-n',
'--negative-strand',
action="store_true",
help="Set flag in conjunction with -B to only consider 5' end motifs "
"on the negative strand."
)
cli_motifs.add_argument(
'-o',
'--output-file',
Expand All @@ -693,7 +700,7 @@ def main_cli_parser():
default=0,
action='count',
help='Enable verbose mode to display detailed processing information.')
cli_motifs.set_defaults(module='..frag._end_motifs', func='end_motifs')
cli_motifs.set_defaults(module='finaletoolkit.frag._end_motifs', func='end_motifs')

# interval-end-motifs
cli_interval_motifs = subparsers.add_parser(
Expand Down Expand Up @@ -782,7 +789,7 @@ def main_cli_parser():
default=0,
action='count',
help='Enable verbose mode to display detailed processing information.')
cli_interval_motifs.set_defaults(module='..frag._end_motifs', func='interval_end_motifs')
cli_interval_motifs.set_defaults(module='finaletoolkit.frag._end_motifs', func='interval_end_motifs')

# mds
cli_mds = subparsers.add_parser(
Expand All @@ -807,7 +814,7 @@ def main_cli_parser():
default=0,
type=int,
help='Number of header rows to ignore. Default is 0')
cli_mds.set_defaults(module='..frag._end_motifs', func='_cli_mds')
cli_mds.set_defaults(module='finaletoolkit.frag._end_motifs', func='_cli_mds')

# interval-mds
cli_interval_mds = subparsers.add_parser(
Expand Down Expand Up @@ -837,7 +844,7 @@ def main_cli_parser():
default=0,
type=int,
help='Number of header rows to ignore. Default is 0')
cli_interval_mds.set_defaults(module='..frag._end_motifs', func='_cli_interval_mds')
cli_interval_mds.set_defaults(module='finaletoolkit.frag._end_motifs', func='_cli_interval_mds')

# filter-bam
cli_filter_bam = subparsers.add_parser(
Expand Down Expand Up @@ -904,7 +911,7 @@ def main_cli_parser():
'--verbose',
action='count',
help='Enable verbose mode to display detailed processing information.')
cli_filter_bam.set_defaults(module='..utils', func='filter_bam')
cli_filter_bam.set_defaults(module='finaletoolkit.utils', func='filter_bam')

# agg-bw
cli_agg_bw = subparsers.add_parser(
Expand Down Expand Up @@ -945,7 +952,7 @@ def main_cli_parser():
action='count',
help='Enable verbose mode to display detailed processing '
'information.')
cli_agg_bw.set_defaults(module='..utils._agg_bw', func='agg_bw')
cli_agg_bw.set_defaults(module='finaletoolkit.utils._agg_bw', func='agg_bw')

# gap-bed
cli_gap_bed = subparsers.add_parser(
Expand All @@ -965,7 +972,7 @@ def main_cli_parser():
cli_gap_bed.add_argument(
'output_file',
help='Path to write BED file to. If "-" used, writes to stdout.')
cli_gap_bed.set_defaults(module='..genome.gaps', func='_cli_gap_bed')
cli_gap_bed.set_defaults(module='finaletoolkit.genome.gaps', func='_cli_gap_bed')

return parser

Expand All @@ -984,7 +991,7 @@ def main_cli():
func_module = funcargs.pop('module')
func_name = funcargs.pop('func')

module = importlib.import_module(func_module, 'finaletoolkit.cli')
module = importlib.import_module(func_module)
function = getattr(module, func_name)

function(**funcargs)
Expand Down
4 changes: 2 additions & 2 deletions src/finaletoolkit/frag/_end_motifs.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,9 +571,9 @@ def region_end_motifs(
if verbose:
start_time = time()

if not both_strands and negative_strand:
if both_strands and negative_strand:
raise ValueError(
'Cannot have both both_strands=False and negative_strand=True.')
'Cannot have both both_strands and negative_strand.')

# iterable of fragments
frag_ends = frag_generator(
Expand Down
1 change: 1 addition & 0 deletions src/finaletoolkit/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ def frag_generator(
"input_file is does not follow Fragmentation file format "
"accepted by FinaleToolkit. Attempting to read as a BED6 "
"file.",
UserWarning
)
bed_format = True
else:
Expand Down
2 changes: 1 addition & 1 deletion src/finaletoolkit/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
Single-source module for the package version number.
"""

__version__ = "0.9.1"
__version__ = "0.10.1"
12 changes: 12 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""
import os
from inspect import getfullargspec
import importlib

import pytest

Expand All @@ -17,6 +18,17 @@ class TestCLIArgs:
"""
Test if provided commandline flags match args in associated function.
"""
@pytest.mark.parametrize("name,subparser", subcommands.items())
def test_lazy_import(self, name, subparser):
# getting module and func
module = subparser._defaults['module']
func = subparser._defaults['func']

# try to see module spec
module = importlib.import_module(module)
function = getattr(module, func)
assert callable(function), f'The {func} is not a callable in {module}.'

@pytest.mark.skip(reason="Currently does not work with the lazy loading implementation")
@pytest.mark.skipif(
IN_GITHUB_ACTIONS,
Expand Down
10 changes: 6 additions & 4 deletions tests/test_frag_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"""

import numpy as np
import pytest

from finaletoolkit.utils.utils import frag_generator, frag_array, overlaps

Expand Down Expand Up @@ -58,10 +59,11 @@ def test_bed_gz(self, request):
right number of reads
"""
path = request.path.parent / 'data' / '12.3444.b37.frag.bed.gz'
frag_gen = frag_generator(
path, "12", quality_threshold=0, min_length=0, max_length=9999
)
frags = [frag for frag in frag_gen]
with pytest.warns(UserWarning):
frag_gen = frag_generator(
path, "12", quality_threshold=0, min_length=0, max_length=9999
)
frags = [frag for frag in frag_gen]

chroms = np.array([chrom for chrom, *_ in frags])
starts = np.array([start for _, start, *_ in frags])
Expand Down
Loading