Skip to content

Commit

Permalink
Add support for FusionCatcher
Browse files Browse the repository at this point in the history
  • Loading branch information
bow committed May 20, 2016
1 parent 1d23aa7 commit 067a921
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 0 deletions.
2 changes: 2 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Release 0.2.0

`release date: TBD`

* Adds support for plotting FusionCatcher output.


Versions 0.1
------------
Expand Down
2 changes: 2 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ Currently it accepts outputs of the following gene fusion finding tool:

* `STAR-Fusion <https://github.com/STAR-Fusion/STAR-Fusion>`_ hits table
(``star-fusion``)
* `FusionCatcher <https://github.com/ndaniel/fusioncatcher>`_ final table
(``fusioncatcher``)


Requirements
Expand Down
69 changes: 69 additions & 0 deletions fsnviz/fusioncatcher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# -*- coding: utf-8 -*-
"""
fsnviz.fusioncatcher
~~~~~~~~~~~~~~~~~~~~
FusionCatcher output plotting.
:copyright: (c) 2016 Wibowo Arindrarto <[email protected]>
:license: BSD
"""
from crimson.fusioncatcher import parse

from .models import CircosEntry, CircosLabel, CircosLink, FusionToolResults
from .utils import adjust_chrom


__all__ = ["FusionCatcherResults"]


class FusionCatcherResults(FusionToolResults):

"""Class representing a FusionCatcher run result."""

mito_names = ("chrM", "M", "MT")

def __init__(self, results_fname, config, tpl_params):
super().__init__(results_fname, config, tpl_params)
self.payload = parse(results_fname)

def _make_circos_entry(self, raw_entry):
left = raw_entry["5end"]
right = raw_entry["3end"]
if left["chromosome"] in self.mito_names:
return
if right["chromosome"] in self.mito_names:
return
lchrom = adjust_chrom(left["chromosome"])
rchrom = adjust_chrom(right["chromosome"])

link = CircosLink(lchrom, left["position"], left["position"] + 1,
rchrom, right["position"], right["position"] + 1)

geneA = CircosLabel(lchrom, left["position"], left["position"] + 1,
left["geneSymbol"])
geneB = CircosLabel(rchrom, right["position"], right["position"] + 1,
right["geneSymbol"])

njr = raw_entry["nSpanningUniqueReads"]
nsf = raw_entry["nSpanningPairs"]

jrA = CircosLabel(lchrom, left["position"], left["position"] + 1,
njr)
jrB = CircosLabel(rchrom, right["position"], right["position"] + 1,
njr)

sfA = CircosLabel(lchrom, left["position"], left["position"] + 1,
nsf)
sfB = CircosLabel(rchrom, right["position"], right["position"] + 1,
nsf)

return CircosEntry(link, [geneA, geneB], [jrA, jrB], [sfA, sfB])

@property
def circos_entries(self):
if not hasattr(self, "_circos_entries"):
entries = [self._make_circos_entry(x) for x in self.payload]
self._circos_entries = list(filter(None, entries))
return self._circos_entries
11 changes: 11 additions & 0 deletions fsnviz/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

from . import __version__
from .models import FsnVizConfig
from .fusioncatcher import FusionCatcherResults
from .star_fusion import STARFusionResults
from .utils import which_circos, get_karyotype_file as gkf

Expand Down Expand Up @@ -76,3 +77,13 @@ def star_fusion(ctx, input):
res = STARFusionResults(input, ctx.parent.params["_config"],
ctx.parent.params["_j2"])
res.plot()


@cli.command(name="fusioncatcher")
@click.argument("input", type=click.File("r"))
@click.pass_context
def fusioncatcher(ctx, input):
"""Plots output of FusionCatcher."""
res = FusionCatcherResults(input, ctx.parent.params["_config"],
ctx.parent.params["_j2"])
res.plot()
60 changes: 60 additions & 0 deletions fsnviz/tests/cases/fusioncatcher_v0995a_01.txt

Large diffs are not rendered by default.

80 changes: 80 additions & 0 deletions fsnviz/tests/test_fusioncatcher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# -*- coding: utf-8 -*-
"""
fsnviz.tests.test_fusioncatcher
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FusionCatcher subcommand tests.
:copyright: (c) 2016 Wibowo Arindrarto <[email protected]>
:license: BSD
"""
from os import path

from click.testing import CliRunner

from fsnviz.main import cli
from .utils import get_test_path


FNAME1 = get_test_path("fusioncatcher_v0995a_01.txt")


def test_fusioncatcher_ok():
runner = CliRunner()
with runner.isolated_filesystem():
cmd = runner.invoke(cli, ["fusioncatcher", FNAME1])
assert cmd.exit_code == 0
assert path.exists("fsnviz.svg")


def test_fusioncatcher_circos_exe_fail():
runner = CliRunner()
with runner.isolated_filesystem():
params = ["--circos-exe", "/nonexistent/file"]
cmd = runner.invoke(cli, params + ["fusioncatcher", FNAME1])
assert cmd.exit_code != 0
assert "Could not find an executable circos at '/nonexistent/file'" \
in cmd.output
assert not path.exists("fsnviz.svg")


def test_fusioncatcher_out_dir_ok():
runner = CliRunner()
with runner.isolated_filesystem():
out_dir = "my_dir"
params = ["--out-dir", out_dir]
cmd = runner.invoke(cli, params + ["fusioncatcher", FNAME1])
assert cmd.exit_code == 0
assert path.exists(path.join(out_dir, "fsnviz.svg"))
assert not path.exists("fsnviz.svg")


def test_fusioncatcher_base_name_ok():
runner = CliRunner()
with runner.isolated_filesystem():
base_name = "my_stuff"
params = ["--base-name", base_name]
cmd = runner.invoke(cli, params + ["fusioncatcher", FNAME1])
assert cmd.exit_code == 0
assert path.exists("{0}.svg".format(base_name))
assert not path.exists("fsnviz.svg")


def test_fusioncatcher_karyotype_ok():
runner = CliRunner()
with runner.isolated_filesystem():
params = ["--karyotype", "human.hg19"]
cmd = runner.invoke(cli, params + ["fusioncatcher", FNAME1])
assert cmd.exit_code == 0
assert path.exists("fsnviz.svg")


def test_fusioncatcher_karyotype_png_ok():
runner = CliRunner()
with runner.isolated_filesystem():
params = ["--png"]
cmd = runner.invoke(cli, params + ["fusioncatcher", FNAME1])
assert cmd.exit_code == 0
assert path.exists("fsnviz.svg")
assert path.exists("fsnviz.png")

0 comments on commit 067a921

Please sign in to comment.