Skip to content

Commit

Permalink
Merge pull request #267 from bcgsc/feature/python3.9-10
Browse files Browse the repository at this point in the history
Feature/python3.9 10
  • Loading branch information
creisle authored Jan 4, 2022
2 parents 6b6dc65 + ca06372 commit b14c908
Show file tree
Hide file tree
Showing 12 changed files with 142 additions and 145 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.7", "3.8"]
python-version: ["3.7", "3.8", "3.9", "3.10"]
name: python-${{ matrix.python-version }}
steps:
- uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/quick-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.7", "3.8"]
python-version: ["3.7", "3.8", "3.9", "3.10"]
name: python-${{ matrix.python-version }} quick
steps:
- uses: actions/checkout@v2
Expand Down
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ RUN wget http://hgdownload.soe.ucsc.edu/admin/exe/linux.x86_64/blat/blat && \

COPY setup.py setup.py
COPY setup.cfg setup.cfg
COPY MANIFEST.in MANIFEST.in
COPY pyproject.toml pyproject.toml
COPY src src
COPY LICENSE LICENSE
COPY README.md README.md
Expand Down
4 changes: 2 additions & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
recursive-include src *.py *.json
include README.md
include LICENSE
prune docs/build
prune docs/source/auto
prune docs
prune tests
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build-backend = "setuptools.build_meta"
100 changes: 87 additions & 13 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,23 +1,97 @@
[nosetests]
with-coverage=1
cover-package=mavis,tab
cover-html=1
cover-html-dir=coverage
cover-inclusive=1
cover-erase=1
processes=2
process-timeout=600

[metadata]
description-file = README.md
name = mavis
version = 2.2.10
url = https://github.com/bcgsc/mavis.git
download_url = https://github.com/bcgsc/mavis/archive/v2.2.10.tar.gz
description = A Structural Variant Post-Processing Package
author_email = [email protected]
author = Caralyn Reisle
maintainer_email = [email protected]
maintainer = mavis
long_description = file: README.md
long_description_content_type = text/markdown
license_file = LICENSE
project_urls = mavis = http://mavis.bcgsc.ca

[bdist_wheel]
universal = 1

[pycodestyle]
ignore = E501,W503,E203
ignore = E501
W503
E203
statistics = True

[flake8]
ignore = E501,W503,E203
ignore = E501
W503
E203

[options]
packages = find:
package_dir =
= src
python_requires = >=3.7
dependency_links = []
include_package_data = True
install_requires =
biopython>=1.70, <1.78
braceexpand==0.1.2
colour
Distance>=0.1.3
mavis_config>=1.1.0, <2.0.0
networkx>=2.5,<3
numpy>=1.13.1
pandas>=1.1, <2
pysam
Shapely>=1.6.4.post1
shortuuid>=0.5.0
svgwrite
typing_extensions>=4
setup_requires =
pip>=9.0.0
setuptools>=36.0.0

[options.packages.find]
exclude = tests
where = src

[options.extras_require]
doc =
mkdocs==1.1.2
markdown-refdocs
mkdocs-material==5.4.0
markdown-include
mkdocs-simple-hooks==0.1.2
test =
timeout-decorator>=0.3.3
coverage>=4.2
pycodestyle>=2.3.1
pytest
pytest-cov
dev =
black
flake8
twine
wheel
timeout-decorator>=0.3.3
coverage>=4.2
pycodestyle>=2.3.1
pytest
pytest-cov
mkdocs==1.1.2
markdown-refdocs
mkdocs-material==5.4.0
markdown-include
mkdocs-simple-hooks==0.1.2
deploy =
twine
wheel
tools =
pyensembl
simplejson

[options.entry_points]
console_scripts =
mavis = mavis.main:main
calculate_ref_alt_counts = tools.calculate_ref_alt_counts:main
105 changes: 2 additions & 103 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,7 @@
import os
import re

from setuptools import find_packages, setup

VERSION = '2.2.8'


def parse_md_readme():
"""
pypi won't render markdown. After conversion to rst it will still not render unless raw directives are removed
"""
try:
from m2r import parse_from_file

rst_lines = parse_from_file('README.md').split('\n')
long_description = [
'.. image:: http://mavis.bcgsc.ca/docs/latest/_static/acronym.svg\n\n|\n'
] # backup since pip can't handle raw directives
i = 0
while i < len(rst_lines):
if re.match(r'^..\s+raw::.*', rst_lines[i]):
i += 1
while re.match(r'^(\s\s+|\t|$).*', rst_lines[i]):
i += 1
else:
long_description.append(re.sub('>`_ ', '>`__ ', rst_lines[i])) # anonymous links
i += 1
long_description = '\n'.join(long_description)
except (ImportError, OSError):
long_description = ''
return long_description
from setuptools import setup


def check_nonpython_dependencies():
Expand All @@ -54,78 +26,5 @@ def check_nonpython_dependencies():
print('Found: aligner at', pth)


# HSTLIB is a dependency for pysam.
# The cram file libraries fail for some OS versions and mavis does not use cram files so we disable these options
os.environ['HTSLIB_CONFIGURE_OPTIONS'] = '--disable-lzma --disable-bz2 --disable-libcurl'


TEST_REQS = [
'timeout-decorator>=0.3.3',
'coverage>=4.2',
'pycodestyle>=2.3.1',
'pytest',
'pytest-cov',
]


DOC_REQS = [
'mkdocs==1.1.2',
'markdown_refdocs',
'mkdocs-material==5.4.0',
'markdown-include',
'mkdocs-simple-hooks==0.1.2',
]


INSTALL_REQS = [
'Distance>=0.1.3',
'Shapely>=1.6.4.post1',
'biopython>=1.70, <1.78',
'braceexpand==0.1.2',
'colour',
'networkx==1.11.0',
'numpy>=1.13.1',
'pandas>=1.1, <2',
'pysam',
'shortuuid>=0.5.0',
'svgwrite',
'mavis_config>=1.1.0, <2.0.0',
]

DEPLOY_REQS = ['twine', 'm2r', 'wheel']


setup(
name='mavis',
version='{}'.format(VERSION),
url='https://github.com/bcgsc/mavis.git',
download_url='https://github.com/bcgsc/mavis/archive/v{}.tar.gz'.format(VERSION),
package_dir={'': 'src'},
packages=find_packages(where='src'),
description='A Structural Variant Post-Processing Package',
long_description=parse_md_readme(),
install_requires=INSTALL_REQS,
extras_require={
'docs': DOC_REQS,
'test': TEST_REQS,
'dev': ['black==20.8b1', 'flake8'] + DOC_REQS + TEST_REQS + DEPLOY_REQS,
'deploy': DEPLOY_REQS,
'tools': ['pyensembl', 'simplejson'],
},
tests_require=TEST_REQS,
setup_requires=['pip>=9.0.0', 'setuptools>=36.0.0'],
python_requires='>=3.7',
author='Caralyn Reisle',
author_email='[email protected]',
test_suite='tests',
entry_points={
'console_scripts': [
'mavis = mavis.main:main',
'calculate_ref_alt_counts = tools.calculate_ref_alt_counts:main',
]
},
include_package_data=True,
data_files=[('mavis', ['src/mavis/schemas/config.json', 'src/mavis/schemas/overlay.json'])],
project_urls={'mavis': 'http://mavis.bcgsc.ca'},
)
setup()
check_nonpython_dependencies()
35 changes: 22 additions & 13 deletions src/mavis/assemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ class DeBruijnGraph(nx.DiGraph):
enforces edge weights
"""

def get_out_edges(self, *args, **kwargs):
return list(self.out_edges(*args, **kwargs))

def get_in_edges(self, *args, **kwargs):
return list(self.in_edges(*args, **kwargs))

def get_nodes(self, *args, **kwargs):
return list(self.nodes(*args, **kwargs))

def get_edge_freq(self, n1, n2):
"""
returns the freq from the data attribute for a specified edge
Expand All @@ -85,7 +94,7 @@ def add_edge(self, n1, n2, freq=1):
nx.DiGraph.add_edge(self, n1, n2, freq=freq)

def all_edges(self, *nodes, data=False):
return self.in_edges(*nodes, data=data) + self.out_edges(*nodes, data=data)
return self.get_in_edges(*nodes, data=data) + self.get_out_edges(*nodes, data=data)

def trim_tails_by_freq(self, min_weight):
"""
Expand All @@ -95,7 +104,7 @@ def trim_tails_by_freq(self, min_weight):
min_weight (int): the minimum weight for an edge to be retained
"""
ends = sorted(
[n for n in self.nodes() if self.out_degree(n) == 0 or self.in_degree(n) == 0]
[n for n in self.get_nodes() if self.out_degree(n) == 0 or self.in_degree(n) == 0]
)
visited = set()

Expand Down Expand Up @@ -126,16 +135,16 @@ def trim_forks_by_freq(self, min_weight):
for all nodes in the graph, if the node has an out-degree > 1 and one of the outgoing
edges has freq < min_weight. then that outgoing edge is deleted
"""
nodes = [n for n in self.nodes() if self.degree(n) > 2]
nodes = [n for n in self.get_nodes() if self.degree(n) > 2]
for node in sorted(nodes):
if self.out_degree(node) > 1:
outgoing_edges = self.out_edges(node, data=True)
outgoing_edges = self.get_out_edges(node, data=True)
best = max([e[2]['freq'] for e in outgoing_edges])
for src, tgt, data in outgoing_edges:
if data['freq'] < min_weight and data['freq'] != best:
self.remove_edge(src, tgt)
if self.in_degree(node) > 1:
ingoing_edges = self.in_edges(node, data=True)
ingoing_edges = self.get_in_edges(node, data=True)
best = max([e[2]['freq'] for e in ingoing_edges])
for src, tgt, data in ingoing_edges:
if data['freq'] < min_weight and data['freq'] != best:
Expand All @@ -157,15 +166,15 @@ def trim_noncutting_paths_by_freq(self, min_weight):
else:
path = []
while self.in_degree(src) == 1 and self.out_degree(src) == 1:
s, t, data = self.in_edges(src, data=True)[0]
s, t, data = self.get_in_edges(src, data=True)[0]
if data['freq'] >= min_weight or s in path:
break
path.insert(0, src)
src = s
path.insert(0, src)

while self.in_degree(tgt) == 1 and self.out_degree(tgt) == 1:
s, t, data = self.out_edges(tgt, data=True)[0]
s, t, data = self.get_out_edges(tgt, data=True)[0]
if data['freq'] >= min_weight or t in path:
break
path.append(tgt)
Expand Down Expand Up @@ -193,7 +202,7 @@ def get_sinks(self, subgraph=None):
"""
nodeset = set()
if subgraph is None:
subgraph = self.nodes()
subgraph = self.get_nodes()
for node in subgraph:
if self.out_degree(node) == 0:
nodeset.add(node)
Expand All @@ -205,7 +214,7 @@ def get_sources(self, subgraph=None):
"""
nodeset = set()
if subgraph is None:
subgraph = self.nodes()
subgraph = self.get_nodes()
for node in subgraph:
if self.in_degree(node) == 0:
nodeset.add(node)
Expand All @@ -227,7 +236,7 @@ def digraph_connected_components(graph, subgraph=None):
List[List]: returns a list of compnents which are lists of node names
"""
if subgraph is None:
subgraph = set(graph.nodes())
subgraph = set(graph.get_nodes())
g = nx.Graph()
for src, tgt in graph.edges():
if src in subgraph and tgt in subgraph:
Expand Down Expand Up @@ -387,7 +396,7 @@ def assemble(
for kmer in kmers_list:
assembly.add_edge(kmer[:-1], kmer[1:])
# use the ab min edge weight to remove all low weight edges first
nodes = list(assembly.nodes())
nodes = assembly.get_nodes()
for n in nodes:
if assembly.in_degree(n) == 0 and assembly.out_degree(n) == 0:
assembly.remove_node(n)
Expand All @@ -396,7 +405,7 @@ def assemble(
subgraph = assembly.subgraph(component)
if not nx.is_directed_acyclic_graph(subgraph):
log('dropping cyclic component', time_stamp=False)
for node in subgraph.nodes():
for node in subgraph.get_nodes():
assembly.remove_node(node)
# initial data cleaning
assembly.trim_forks_by_freq(min_edge_trim_weight)
Expand All @@ -409,7 +418,7 @@ def assemble(
# pull the path scores
path_scores.update(
pull_contigs_from_component(
assembly.subgraph(component),
assembly.subgraph(component).copy(),
component,
min_edge_trim_weight=min_edge_trim_weight,
assembly_max_paths=assembly_max_paths,
Expand Down
Loading

0 comments on commit b14c908

Please sign in to comment.