diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 0000000..757cae6 --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,8 @@ +name: Ruff +on: [ push, pull_request ] +jobs: + ruff: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: chartboost/ruff-action@v1 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9ec00a5..99c824c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,9 +7,9 @@ jobs: build-and-publish: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' - name: Install dependencies diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 17ce346..3443628 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -4,9 +4,9 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' - name: Install dependencies @@ -21,9 +21,9 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: '3.x' - name: Install dependencies diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d4c946e..7ffb91e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,9 +11,9 @@ jobs: build-and-publish: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' - name: Install dependencies diff --git a/browser.py b/browser.py index f97fddc..fed5496 100644 --- a/browser.py +++ b/browser.py @@ -22,14 +22,16 @@ ix = "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/trix/hg38.ix" ixx = "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/trix/hg38.ixx" meta = "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/trix/meta.json" -jbrowse_conf.set_assembly(assembly_data, - aliases=aliases, - refname_aliases=ref_name_aliases) +jbrowse_conf.set_assembly( + assembly_data, aliases=aliases, refname_aliases=ref_name_aliases +) # add a track -track_data = "https://s3.amazonaws.com/jbrowse.org/genomes/" \ - "GRCh38/ncbi_refseq/GCA_000001405.15_GRCh38_full" \ - "_analysis_set.refseq_annotation.sorted.gff.gz" +track_data = ( + "https://s3.amazonaws.com/jbrowse.org/genomes/" + "GRCh38/ncbi_refseq/GCA_000001405.15_GRCh38_full" + "_analysis_set.refseq_annotation.sorted.gff.gz" +) jbrowse_conf.add_track(track_data, name="test-demo", track_id="test-track") # deleting a track jbrowse_conf.add_track(track_data, name="delete", track_id="test-delete-track") @@ -50,10 +52,7 @@ component = create_component(config) # launch the component -app.layout = html.Div( - [component], - id='test' -) +app.layout = html.Div([component], id="test") if __name__ == "__main__": app.run_server(port=3001, debug=True) diff --git a/jbrowse_jupyter/data/hg19.json b/jbrowse_jupyter/data/hg19.json deleted file mode 100644 index e3bb66a..0000000 --- a/jbrowse_jupyter/data/hg19.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "configuration": {}, - "assembly": { - "name": "hg19", - "aliases": ["GRCh37"], - "sequence": { - "type": "ReferenceSequenceTrack", - "trackId": "hg19-ReferenceSequenceTrack", - "adapter": { - "type": "BgzipFastaAdapter", - "fastaLocation": { - "uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz" - }, - "faiLocation": { - "uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.fai" - }, - "gziLocation": { - "uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.gzi" - } - } - }, - "refNameAliases": { - "adapter": { - "type": "RefNameAliasAdapter", - "location": { - "uri": "https://s3.amazonaws.com/jbrowse.org/genomes/hg19/hg19_aliases.txt" - } - } - } - }, - "tracks": [ - { - "type": "FeatureTrack", - "trackId": "repeats_hg19", - "name": "Repeats", - "assemblyNames": ["hg19"], - "category": ["Annotation"], - "adapter": { - "type": "BigBedAdapter", - "bigBedLocation": { - "uri": "https://jbrowse.org/genomes/hg19/repeats.bb", - "locationType": "UriLocation" - } - } - } - ], - "defaultSession": { - "name": "test", - "view": { - "id": "aU9Nqje1U", - "type": "LinearGenomeView", - "tracks": [ - { - "type": "ReferenceSequenceTrack", - "configuration": "hg19-ReferenceSequenceTrack", - "displays": [ - { - "type": "LinearReferenceSequenceDisplay", - "configuration": "hg19-ReferenceSequenceTrack-LinearReferenceSequenceDisplay" - } - ] - } - ] - } - }, - "location": "1:68654694..68654738" -} diff --git a/jbrowse_jupyter/data/hg19_cgv.json b/jbrowse_jupyter/data/hg19_cgv.json deleted file mode 100644 index c9a3325..0000000 --- a/jbrowse_jupyter/data/hg19_cgv.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "configuration": {}, - "assembly": { - "name": "hg19", - "aliases": ["GRCh37"], - "sequence": { - "type": "ReferenceSequenceTrack", - "trackId": "Pd8Wh30ei9R", - "adapter": { - "type": "BgzipFastaAdapter", - "fastaLocation": { - "uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz", - "locationType": "UriLocation" - }, - "faiLocation": { - "uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.fai", - "locationType": "UriLocation" - }, - "gziLocation": { - "uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.gzi", - "locationType": "UriLocation" - } - } - }, - "refNameAliases": { - "adapter": { - "type": "RefNameAliasAdapter", - "location": { - "uri": "https://s3.amazonaws.com/jbrowse.org/genomes/hg19/hg19_aliases.txt", - "locationType": "UriLocation" - } - } - } - }, - "tracks": [ - { - "type": "VariantTrack", - "trackId": "pacbio_sv_vcf", - "name": "HG002 Pacbio SV (VCF)", - "assemblyNames": ["hg19"], - "category": ["GIAB"], - "adapter": { - "type": "VcfTabixAdapter", - "vcfGzLocation": { - "uri": "https://s3.amazonaws.com/jbrowse.org/genomes/hg19/pacbio/hs37d5.HG002-SequelII-CCS.bnd-only.sv.vcf.gz", - "locationType": "UriLocation" - }, - "index": { - "location": { - "uri": "https://s3.amazonaws.com/jbrowse.org/genomes/hg19/pacbio/hs37d5.HG002-SequelII-CCS.bnd-only.sv.vcf.gz.tbi", - "locationType": "UriLocation" - } - } - } - } - ], - "defaultSession": { - "name": "My session", - "view": { - "id": "circularView", - "type": "CircularView", - "bpPerPx": 5000000, - "tracks": [ - { - "id": "uPdLKHik1", - "type": "VariantTrack", - "configuration": "pacbio_sv_vcf", - "displays": [ - { - "id": "v9QVAR3oaB", - "type": "ChordVariantDisplay", - "configuration": "pacbio_sv_vcf-ChordVariantDisplay" - } - ] - } - ] - } - } -} diff --git a/jbrowse_jupyter/data/hg38.json b/jbrowse_jupyter/data/hg38.json deleted file mode 100644 index efa741b..0000000 --- a/jbrowse_jupyter/data/hg38.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "configuration": {}, - "assembly": { - "name": "GRCh38", - "sequence": { - "type": "ReferenceSequenceTrack", - "trackId": "GRCh38-ReferenceSequenceTrack", - "adapter": { - "type": "BgzipFastaAdapter", - "fastaLocation": { - "uri": "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/fasta/GRCh38.fa.gz" - }, - "faiLocation": { - "uri": "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/fasta/GRCh38.fa.gz.fai" - }, - "gziLocation": { - "uri": "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/fasta/GRCh38.fa.gz.gzi" - } - } - }, - "aliases": ["hg38"], - "refNameAliases": { - "adapter": { - "type": "RefNameAliasAdapter", - "location": { - "uri": "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/hg38_aliases.txt" - } - } - } - }, - "tracks": [ - { - "type": "FeatureTrack", - "trackId": "ncbi_refseq_109_hg38", - "name": "NCBI RefSeq (GFF3Tabix)", - "assemblyNames": ["GRCh38"], - "category": ["Annotation"], - "adapter": { - "type": "Gff3TabixAdapter", - "gffGzLocation": { - "uri": "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/ncbi_refseq/GCA_000001405.15_GRCh38_full_analysis_set.refseq_annotation.sorted.gff.gz" - }, - "index": { - "location": { - "uri": "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/ncbi_refseq/GCA_000001405.15_GRCh38_full_analysis_set.refseq_annotation.sorted.gff.gz.tbi" - } - } - } - } - ], - "location": "10:29,838,737..29,838,819", - "defaultSession": { - "name": "My session", - "view": { - "id": "linearGenomeView", - "type": "LinearGenomeView", - "tracks": [ - { - "type": "ReferenceSequenceTrack", - "configuration": "GRCh38-ReferenceSequenceTrack", - "displays": [ - { - "type": "LinearReferenceSequenceDisplay", - "configuration": "GRCh38-ReferenceSequenceTrack-LinearReferenceSequenceDisplay" - } - ] - } - ] - } - } -} diff --git a/jbrowse_jupyter/data/hg38_cgv.json b/jbrowse_jupyter/data/hg38_cgv.json deleted file mode 100644 index bbe12e4..0000000 --- a/jbrowse_jupyter/data/hg38_cgv.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "configuration": {}, - "assembly": { - "name": "hg38", - "sequence": { - "type": "ReferenceSequenceTrack", - "trackId": "GRCh38-ReferenceSequenceTrack", - "adapter": { - "type": "BgzipFastaAdapter", - "fastaLocation": { - "uri": "https://jbrowse.org/genomes/GRCh38/fasta/hg38.prefix.fa.gz", - "locationType": "UriLocation" - }, - "faiLocation": { - "uri": "https://jbrowse.org/genomes/GRCh38/fasta/hg38.prefix.fa.gz.fai", - "locationType": "UriLocation" - }, - "gziLocation": { - "uri": "https://jbrowse.org/genomes/GRCh38/fasta/hg38.prefix.fa.gz.gzi", - "locationType": "UriLocation" - } - } - }, - "aliases": ["GRCh38"], - "refNameAliases": { - "adapter": { - "type": "RefNameAliasAdapter", - "location": { - "uri": "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/hg38_aliases.txt", - "locationType": "UriLocation" - } - } - } - }, - "tracks": [], - "defaultSession": { - "name": "My session", - "view": { - "id": "circularView", - "type": "CircularView", - "bpPerPx": 5000000, - "tracks": [] - } - } -} diff --git a/jbrowse_jupyter/dev_server.py b/jbrowse_jupyter/dev_server.py index 24881d0..0b8c32b 100644 --- a/jbrowse_jupyter/dev_server.py +++ b/jbrowse_jupyter/dev_server.py @@ -91,7 +91,8 @@ def send_head(self): last = file_len - 1 response_length = last - first + 1 - self.send_header("Content-Range", "bytes %s-%s/%s" % (first, last, file_len)) + self.send_header("Content-Range", "bytes %s-%s/%s" % + (first, last, file_len)) self.send_header("Content-Length", str(response_length)) self.send_header("Last-Modified", self.date_time_string(fs.st_mtime)) self.end_headers() diff --git a/jbrowse_jupyter/jbrowse_config.py b/jbrowse_jupyter/jbrowse_config.py index a1bc2d6..4f6076f 100644 --- a/jbrowse_jupyter/jbrowse_config.py +++ b/jbrowse_jupyter/jbrowse_config.py @@ -35,10 +35,12 @@ def create(view_type="LGV", **kwargs): conf = kwargs.get("conf", {}) genome = kwargs.get("genome", "empty") view = view_type + # view type (LGV or CGV) # make it backwards compatible if view_type == "view" or view_type == "conf": view = "LGV" + if view != "LGV" and view != "CGV": raise TypeError(f"Currently not supporting view_type: {view}.") # configuration @@ -51,13 +53,10 @@ def create(view_type="LGV", **kwargs): message2 = "Choose from hg19 or hg38 or pass your own conf" if genome not in available_genomes and no_configuration: raise TypeError(f'"{genome}" {message1}.{message2}.') - # genome if genome in available_genomes: conf = get_default(genome, view) - # start from empty JBrowseConfig elif not conf: return JBrowseConfig(view=view) - # get customized JBrowseConfig return JBrowseConfig(view=view, conf=conf) @@ -392,8 +391,7 @@ def add_df_track(self, track_data, name, **kwargs): "adapter": adapter, } err = ( - f'track with trackId: "{track_id}" already exists in config.', - "Set overwrite to True if you want to overwrite it.", + f'track with trackId: "{track_id}" already exists in config. Set overwrite to True if you want to overwrite it.', ) if track_id in self.tracks_ids_map.keys() and not overwrite: raise TypeError(err) diff --git a/jbrowse_jupyter/tracks.py b/jbrowse_jupyter/tracks.py index 74f201d..b3b0a99 100644 --- a/jbrowse_jupyter/tracks.py +++ b/jbrowse_jupyter/tracks.py @@ -74,7 +74,8 @@ def guess_display_type(track_type, view="LGV"): else: if view == "CGV": return "ChordVariantDisplay" - return "LinearBasicDisplay" + else: + return "LinearBasicDisplay" def guess_track_type(adapter_type): diff --git a/jbrowse_jupyter/util.py b/jbrowse_jupyter/util.py index 599d54c..2cfb8fb 100644 --- a/jbrowse_jupyter/util.py +++ b/jbrowse_jupyter/util.py @@ -1,12 +1,123 @@ import re +import copy import os -import json -import importlib import dash_jbrowse as jb from dash import html, Dash from urllib.parse import urlparse +hg38_assembly = { + "name": "hg38", + "sequence": { + "type": "ReferenceSequenceTrack", + "trackId": "GRCh38-ReferenceSequenceTrack", + "adapter": { + "type": "BgzipFastaAdapter", + "fastaLocation": { + "uri": "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/fasta/GRCh38.fa.gz" + }, + "faiLocation": { + "uri": "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/fasta/GRCh38.fa.gz.fai" + }, + "gziLocation": { + "uri": "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/fasta/GRCh38.fa.gz.gzi" + }, + }, + }, + "aliases": ["GRCh38"], + "refNameAliases": { + "adapter": { + "type": "RefNameAliasAdapter", + "location": { + "uri": "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/hg38_aliases.txt" + }, + } + }, +} +hg38_lgv = { + "assembly": hg38_assembly, + "tracks": [], + "location": "10:29,838,737..29,838,819", + "defaultSession": { + "name": "My session", + "view": { + "id": "linearGenomeView", + "type": "LinearGenomeView", + "tracks": [], + }, + }, +} + + +hg38_cgv = { + "assembly": hg38_assembly, + "tracks": [], + "defaultSession": { + "name": "My session", + "view": { + "id": "circularView", + "type": "CircularView", + "bpPerPx": 5000000, + "tracks": [], + }, + }, +} +hg19_assembly = { + "name": "hg19", + "aliases": ["GRCh37"], + "sequence": { + "type": "ReferenceSequenceTrack", + "trackId": "hg19-ReferenceSequenceTrack", + "adapter": { + "type": "BgzipFastaAdapter", + "fastaLocation": { + "uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz" + }, + "faiLocation": { + "uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.fai" + }, + "gziLocation": { + "uri": "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz.gzi" + }, + }, + }, + "refNameAliases": { + "adapter": { + "type": "RefNameAliasAdapter", + "location": { + "uri": "https://s3.amazonaws.com/jbrowse.org/genomes/hg19/hg19_aliases.txt" + }, + } + }, +} +hg19_lgv = { + "assembly": hg19_assembly, + "tracks": [], + "defaultSession": { + "name": "test", + "view": { + "id": "aU9Nqje1U", + "type": "LinearGenomeView", + "tracks": [], + }, + }, + "location": "1:68654694..68654738", +} + +hg19_cgv = { + "assembly": hg19_assembly, + "tracks": [], + "defaultSession": { + "name": "My session", + "view": { + "id": "circularView", + "type": "CircularView", + "bpPerPx": 5000000, + "tracks": [], + }, + }, +} + def is_url(filePath): """ @@ -38,11 +149,11 @@ def get_name(assembly_file): name_end = 0 name_start = 0 for i in range(0, len(assembly_file)): - if assembly_file[len(assembly_file) - i - 1 : len(assembly_file) - i] == "/": + if assembly_file[len(assembly_file) - i - 1: len(assembly_file) - i] == "/": name_start = len(assembly_file) - i break for i in range(name_start, len(assembly_file)): - if assembly_file[i : i + 1] == ".": + if assembly_file[i: i + 1] == ".": name_end = i break @@ -56,16 +167,16 @@ def get_name_regex(assembly_file): def get_default(name, view_type="LGV"): """Returns the configuration object given a genome name.""" - if view_type == "CGV": - with importlib.resources.open_text( - "jbrowse_jupyter.data", f"{name}_cgv.json" - ) as file: - return json.load(file) - else: - with importlib.resources.open_text( - "jbrowse_jupyter.data", f"{name}.json" - ) as file: - return json.load(file) + if name == "hg38": + if view_type == "CGV": + return copy.deepcopy(hg38_cgv) + else: + return copy.deepcopy(hg38_lgv) + elif name == "hg19": + if view_type == "CGV": + return copy.deepcopy(hg19_cgv) + else: + return copy.deepcopy(hg19_lgv) def create_component(conf, **kwargs): diff --git a/requirements.txt b/requirements.txt index 53e00bb..2208a44 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ dash>=2.11.1 dash-jbrowse>=1.2.0 -Werkzeug==2.0.3 pandas>=1.1.5 IPython>=7.0.0 diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000..5523921 --- /dev/null +++ b/ruff.toml @@ -0,0 +1 @@ +indent-width = 4 diff --git a/tests/test_jbrowse_config.py b/tests/test_jbrowse_config.py index 54387f5..74a6c10 100644 --- a/tests/test_jbrowse_config.py +++ b/tests/test_jbrowse_config.py @@ -41,9 +41,7 @@ def test_set_assembly(): conf.get_assembly_name() assert myError in str(excinfo) # raises an error if you try to add a track before an assembly is set - data = "https://s3.amazonaws.com/jbrowse.org/genomes/" \ - "GRCh38/ncbi_refseq/GCA_000001405.15_GRCh38_full_" \ - "analysis_set.refseq_annotation.sorted.gff.gz" + data = "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/ncbi_refseq/GCA_000001405.15_GRCh38_full_analysis_set.refseq_annotation.sorted.gff.gz" with pytest.raises(Exception) as excinfo: conf.add_track( data, @@ -53,15 +51,16 @@ def test_set_assembly(): # raises an error, there is no local path support in non jupyter envs with pytest.raises(TypeError) as excinfo: conf.set_assembly("/hi/there") - err = (f'Path {"/hi/there"} for assembly data is used' - ' in an unsupported environment.' - 'Paths are supported in Jupyter notebooks and Jupyter lab.' - 'Please use a url for your assembly data. You can check out ' - 'our local file support docs for more information') + err = ( + f'Path {"/hi/there"} for assembly data is used' + ' in an unsupported environment.' + 'Paths are supported in Jupyter notebooks and Jupyter lab.' + 'Please use a url for your assembly data. You can check out ' + 'our local file support docs for more information' + ) assert err == excinfo.value.args[0] aliases = ["hg38"] - uri = "https://s3.amazonaws.com/jbrowse.org/genomes/" \ - "GRCh38/hg38_aliases.txt" + uri = "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/hg38_aliases.txt" ref_name_aliases = { "adapter": { "type": "RefNameAliasAdapter", @@ -84,39 +83,34 @@ def test_set_assembly(): ) assert err in str(excinfo) assert conf.get_assembly_name() == "hg38" - track_data = "https://s3.amazonaws.com/jbrowse.org/" \ - "genomes/GRCh38/ncbi_refseq/GCA_000001405.15_" \ + track_data = ( + "https://s3.amazonaws.com/jbrowse.org/" + "genomes/GRCh38/ncbi_refseq/GCA_000001405.15_" "GRCh38_full_analysis_set.refseq_annotation.sorted.gff.gz" + ) conf.add_track( track_data, name="test-demo", ) assert len(conf.get_tracks()) == 1 - alias_uri = "https://s3.amazonaws.com/jbrowse.org/genomes" \ - "/hg19/hg19_aliases.txt" + alias_uri = "https://s3.amazonaws.com/jbrowse.org/genomes/hg19/hg19_aliases.txt" ref_name = { - "adapter": { - "type": "RefNameAliasAdapter", - "location": { - "uri": alias_uri - } - } + "adapter": {"type": "RefNameAliasAdapter", "location": {"uri": alias_uri}} } - aliases = [ - "GRCh37" - ] + aliases = ["GRCh37"] a_data = "https://jbrowse.org/genomes/hg19/fasta/hg19.fa.gz" - conf.set_assembly(a_data, aliases=aliases, - refname_aliases=ref_name, overwrite=True) - assert conf.get_assembly_name() == 'hg19' + conf.set_assembly(a_data, aliases=aliases, refname_aliases=ref_name, overwrite=True) + assert conf.get_assembly_name() == "hg19" def test_create_view(): "tests creating a view from one of the provided genomes" - genome_error = '"volvox" is not a valid default genome to view.' \ - 'Choose from hg19 or hg38 or pass your own conf.' + genome_error = ( + '"volvox" is not a valid default genome to view.' + "Choose from hg19 or hg38 or pass your own conf." + ) with pytest.raises(TypeError) as excinfo: create("LGV", genome="volvox") assert genome_error in str(excinfo) @@ -124,10 +118,10 @@ def test_create_view(): hg19 = create("LGV", genome="hg19") hg38 = create("LGV", genome="hg38") assert hg19.get_assembly_name() == "hg19" - assert len(hg19.get_tracks()) > 0 + assert len(hg19.get_tracks()) == 0 assert hg19.get_default_session() - assert hg38.get_assembly_name() == "GRCh38" - assert len(hg38.get_tracks()) > 0 + assert hg38.get_assembly_name() == "hg38" + assert len(hg38.get_tracks()) == 0 assert hg38.get_default_session() @@ -169,23 +163,15 @@ def test_create_view_from_conf(): "trackId": "hg19-ReferenceSequenceTrack", "adapter": { "type": "BgzipFastaAdapter", - "fastaLocation": { - "uri": fasta_loc - }, - "faiLocation": { - "uri": fai_loc - }, - "gziLocation": { - "uri": gz_loc - }, + "fastaLocation": {"uri": fasta_loc}, + "faiLocation": {"uri": fai_loc}, + "gziLocation": {"uri": gz_loc}, }, }, "refNameAliases": { "adapter": { "type": "RefNameAliasAdapter", - "location": { - "uri": rloc - }, + "location": {"uri": rloc}, } }, }, @@ -195,7 +181,7 @@ def test_create_view_from_conf(): # can add track assert len(hg19_from_config.get_tracks()) == 0 bigwig = "https://jbrowse.org/genomes/hg19/COLO829/colo_normal.bw" - hg19_from_config.add_track(bigwig, name="example", track_id='delete-test') + hg19_from_config.add_track(bigwig, name="example", track_id="delete-test") assert len(hg19_from_config.get_tracks()) == 1 # can set default session hg19_from_config.set_default_session(["example"]) @@ -208,8 +194,10 @@ def test_create_view_from_conf(): adapter_list = hg19_from_config.get_text_search_adapters() assert len(adapter_list) == 1 - same_adapter = "Adapter already exists for given adapterId: " \ + same_adapter = ( + "Adapter already exists for given adapterId: " "hg19-hg19.ix-index.Provide a different adapter_id" + ) with pytest.raises(Exception) as excinfo: hg19_from_config.add_text_search_adapter(ix, ixx, meta) assert same_adapter in str(excinfo) @@ -222,8 +210,9 @@ def test_empty_config_lgv(): # === empty config === empty_conf = create("LGV") assert empty_conf.get_config() - assembly_error = "Can not get assembly name. " \ - "Please configure the assembly first." + assembly_error = ( + "Can not get assembly name. " "Please configure the assembly first." + ) with pytest.raises(Exception) as excinfo: empty_conf.get_assembly_name() assert assembly_error in str(excinfo) @@ -236,8 +225,9 @@ def test_empty_cgv(): # === empty config === empty_conf = create("CGV") assert empty_conf.get_config() - assembly_error = "Can not get assembly name. " \ - "Please configure the assembly first." + assembly_error = ( + "Can not get assembly name. " "Please configure the assembly first." + ) with pytest.raises(Exception) as excinfo: empty_conf.get_assembly_name() assert assembly_error in str(excinfo) @@ -245,8 +235,10 @@ def test_empty_cgv(): def test_create_view_cgv(): "tests creating a view from one of the provided genomes" - genome_error = '"volvox" is not a valid default genome to view.' \ - 'Choose from hg19 or hg38 or pass your own conf.' + genome_error = ( + '"volvox" is not a valid default genome to view.' + "Choose from hg19 or hg38 or pass your own conf." + ) with pytest.raises(TypeError) as excinfo: create("CGV", genome="volvox") assert genome_error in str(excinfo) @@ -256,7 +248,7 @@ def test_create_view_cgv(): in_colab = hg19.colab assert not in_colab assert hg19.get_assembly_name() == "hg19" - assert len(hg19.get_tracks()) > 0 + assert len(hg19.get_tracks()) == 0 assert hg19.get_default_session() assert hg38.get_assembly_name() == "hg38" # hg38 for cgv does not have tracks diff --git a/tests/test_tracks.py b/tests/test_tracks.py index 1d0e5d4..fe948ef 100644 --- a/tests/test_tracks.py +++ b/tests/test_tracks.py @@ -1,26 +1,20 @@ import pytest import pandas as pd -from jbrowse_jupyter.tracks import ( - make_location, - check_track_data, - get_track_data -) +from jbrowse_jupyter.tracks import make_location, check_track_data, get_track_data from jbrowse_jupyter.jbrowse_config import create -# test files -base = "https://s3.amazonaws.com/jbrowse.org/genomes/" -cram = base + "hg19/skbr3/reads_lr_skbr3.fa_ngmlr-0.2.3_mapped.down.cram" -bam = base + "hg19/amplicon_deep_seq/out.marked.bam" -gff3 = base + "hg19/ncbi_refseq/GRCh37_latest_genomic.sort.gff" -gff3Tabix = base + "GRCh38/ncbi_refseq/GCA_000001405.15_GRCh38_full" \ - "_analysis_set.refseq_annotation.sorted.gff.gz" -vcf = "https://ftp.ncbi.nlm.nih.gov/pub/" \ - "clinvar/vcf_GRCh37/clinvar.vcf" -vcfGz = "https://ftp.ncbi.nlm.nih.gov/pub/" \ - "clinvar/vcf_GRCh38/clinvar.vcf.gz" -bigWig = "http://hgdownload.cse.ucsc.edu/goldenpath/hg38/" \ - "phyloP100way/hg38.phyloP100way.bw" -gff3_tabix_index = gff3Tabix + ".tbi" +cram = "https://s3.amazonaws.com/jbrowse.org/genomes/hg19/skbr3/reads_lr_skbr3.fa_ngmlr-0.2.3_mapped.down.cram" +bam = ( + "https://s3.amazonaws.com/jbrowse.org/genomes/hg19/amplicon_deep_seq/out.marked.bam" +) +gff3 = "https://s3.amazonaws.com/jbrowse.org/genomes/hg19/ncbi_refseq/GRCh37_latest_genomic.sort.gff" +gff3Tabix = "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/ncbi_refseq/GCA_000001405.15_GRCh38_full_analysis_set.refseq_annotation.sorted.gff.gz" +gff3TabixIndex = "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/ncbi_refseq/GCA_000001405.15_GRCh38_full_analysis_set.refseq_annotation.sorted.gff.gz.tbi" +bigWig = ( + "http://hgdownload.cse.ucsc.edu/goldenpath/hg38/phyloP100way/hg38.phyloP100way.bw" +) +vcf = "https://ftp.ncbi.nlm.nih.gov/pub/clinvar/vcf_GRCh37/clinvar.vcf" +vcfGz = "https://ftp.ncbi.nlm.nih.gov/pub/clinvar/vcf_GRCh37/clinvar.vcf.gz" def test_make_location(): @@ -39,7 +33,6 @@ def test_add_track_fail(): def test_alignments(): conf = create("LGV", genome="hg19") - # BAM or CRAM alignment data conf.add_track(cram, name="alignments cram track example") conf.add_track(bam, name="alignments bam track example") cram_track = conf.get_track("alignments cram track example") @@ -51,11 +44,9 @@ def test_alignments(): def test_feature(): conf = create("LGV", genome="hg38") track_error = "Adapter type is not recognized" - # gff is not supported with pytest.raises(TypeError) as excinfo: conf.add_track(gff3, name="gff feature") assert track_error in str(excinfo) - # gff3 is supported conf.add_track(gff3Tabix, name="gff3 feature") gff3_track = conf.get_track("gff3 feature") assert gff3_track[0]["type"] == "FeatureTrack" @@ -71,33 +62,27 @@ def test_add_track_type_fail(): def test_add_track_overwrite(): conf = create("LGV", genome="hg38") - overwrite_err = "track with trackId: " \ - '"GRCh38-test" already exists inconfig.' \ - ' Set overwrite to True to overwrite it.' - conf.add_track(gff3Tabix, name='test') - with pytest.raises(TypeError) as excinfo: - conf.add_track(gff3Tabix, name='test') - assert overwrite_err in str(excinfo) - conf.add_track(gff3Tabix, name='test', overwrite=True) + conf.add_track(gff3Tabix, name="test") + with pytest.raises(TypeError): + conf.add_track(gff3Tabix, name="test") + conf.add_track(gff3Tabix, name="test", overwrite=True) tracks = conf.get_tracks() - # should have one track from hg38 conf + test track == 2 - assert len(tracks) == 2 + assert len(tracks) == 1 def test_add_track_with_index(): conf = create("LGV", genome="hg38") conf.add_track(gff3Tabix, name="test") conf2 = create("LGV", genome="hg38") - conf2.add_track(gff3Tabix, name="test", index=gff3_tabix_index) + conf2.add_track(gff3Tabix, name="test", index=gff3TabixIndex) index_one = conf.get_track("test") - idx = index_one[0]['adapter']['index']['location']['uri'] + idx = index_one[0]["adapter"]["index"]["location"]["uri"] index_two = conf2.get_track("test") - idx2 = index_two[0]['adapter']['index']['location']['uri'] + idx2 = index_two[0]["adapter"]["index"]["location"]["uri"] assert idx == idx2 def test_variant(): - # VCF data conf = create("LGV", genome="hg19") conf.add_track(vcf, name="vcf track") conf.add_track(vcfGz, name="vcfgz track") @@ -106,49 +91,35 @@ def test_variant(): def test_wiggle(): - # bigWig data (quantitative/wiggle) conf = create("LGV", genome="hg19") conf.add_track(bigWig, name="wiggle track") bigwig_track = conf.get_track("wiggle track") assert bigwig_track[0]["type"] == "QuantitativeTrack" -# ==== dataframe track ====== def test_data_frame_track(): - hg38 = create('LGV', genome='hg38') - assert len(hg38.get_tracks()) == 1 + hg38 = create("LGV", genome="hg38") + assert len(hg38.get_tracks()) == 0 data_frame = { "refName": ["1", "1"], "start": [123, 456], "end": [780, 101112], - "name": ["feature1", "feature2"] + "name": ["feature1", "feature2"], } df = pd.DataFrame(data_frame) - hg38.add_df_track(df, 'data_frame_track_name') - data_empty = { - "refName": [], - "start": [], - "end": [], - "name": [] - } - assert len(hg38.get_tracks()) == 2 - # throw error if the dataframe is empty + hg38.add_df_track(df, "data_frame_track_name") + data_empty = {"refName": [], "start": [], "end": [], "name": []} + assert len(hg38.get_tracks()) == 1 df_empty = pd.DataFrame(data_empty) df_error = "DataFrame must not be empty." with pytest.raises(TypeError) as excinfo: - hg38.add_df_track(df_empty, 'empty_data_frame_track') + hg38.add_df_track(df_empty, "empty_data_frame_track") assert df_error in str(excinfo) def test_check_track_data(): - # Test track from dataframe df_error = "Track data must be a DataFrame" - invalid_df = { - "refName": "1", - "start": 123, - "end": 789, - "name": "feature1" - } + invalid_df = {"refName": "1", "start": 123, "end": 789, "name": "feature1"} with pytest.raises(TypeError) as excinfo: check_track_data(invalid_df) assert df_error in str(excinfo) @@ -156,18 +127,17 @@ def test_check_track_data(): "refName": ["1", "1"], "start": [123, 456], "end": [780, 101112], - "name": ["feature1", "feature2"] + "name": ["feature1", "feature2"], } pd.DataFrame(data_frame) def test_check_columns(): - # missing start column column_error = "DataFrame must contain all required columns." invalid_df = { "refName": ["1", "1"], "end": [780, 101112], - "name": ['feature1', 'feature2'] + "name": ["feature1", "feature2"], } df = pd.DataFrame(invalid_df) with pytest.raises(TypeError) as excinfo: @@ -180,7 +150,7 @@ def test_get_df_features(): "refName": ["1", "1"], "start": [123, 456], "end": [780, 101112], - "name": ["feature1", "feature2"] + "name": ["feature1", "feature2"], } df = pd.DataFrame(data_frame) features = get_track_data(df)