├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── documentation.md │ ├── enhancement.md │ └── question.md └── workflows │ └── test.yml ├── .gitignore ├── LICENSE ├── MANIFEST.in ├── README.md ├── RELEASE.md ├── environment.yml ├── ipyigv ├── __init__.py ├── _version.py ├── ipyigv.py ├── options.py ├── public_genomes.json └── tests │ ├── __init__.py │ └── test.py ├── js ├── css │ ├── .widget.css.swp │ └── widget.css ├── package.json ├── src │ ├── embed.js │ ├── extension.js │ ├── index.js │ ├── ipyigv.js │ ├── labplugin.js │ ├── notebook.js │ └── version.js └── webpack.config.js ├── jupyter-igv.json ├── notebooks └── ipyigv.ipynb ├── pyproject.toml ├── setup.cfg └── setup.py /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Report a bug 4 | # based on matplotlib issue template 5 | --- 6 | 7 | 8 | 9 | 10 | ### Bug report 11 | 12 | **Bug summary** 13 | 14 | 15 | 16 | **Code for reproduction** 17 | 18 | 31 | 32 | **Expected outcome** 33 | 34 | 35 | 36 | 37 | **Version Info** 38 | 39 | * ipycytoscape version (`import ipycytoscape; print(ipycytoscape.__version__)`) : 40 | * Python version: 41 | * Jupyter(Lab) version: 42 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Documentation improvement 3 | about: Report parts of the docs that are wrong or unclear 4 | labels: documentation 5 | --- 6 | 7 | 8 | 9 | 10 | ### Problem 11 | 12 | 19 | 20 | 21 | ### Suggested Improvement 22 | 23 | 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/enhancement.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Enhancement/Feature Request 3 | about: Suggest something that could be improved or a New Feature to add 4 | labels: enhancement 5 | --- 6 | 7 | 13 | 14 | ### Problem 15 | 16 | 21 | 22 | ### Proposed Solution 23 | 24 | 28 | 29 | ### Additional context 30 | 31 | 35 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question/Support/Other 3 | about: If you have a usage question 4 | labels: question 5 | --- 6 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | run: 13 | runs-on: ${{ matrix.os }} 14 | 15 | strategy: 16 | fail-fast: false 17 | matrix: 18 | os: [ubuntu-latest, macos-latest] 19 | python-version: [3.8] 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | 24 | - name: Setup conda 25 | uses: conda-incubator/setup-miniconda@v2 26 | with: 27 | mamba-version: "*" 28 | channels: conda-forge 29 | 30 | - name: Mamba install dependencies 31 | shell: bash -l {0} 32 | run: mamba install python=${{ matrix.python-version }} pip yarn 33 | 34 | - name: Mamba install JupyterLab 3 35 | shell: bash -l {0} 36 | run: mamba install jupyterlab=3 ipywidgets=7.6 37 | 38 | - name: Install ipyigv 39 | shell: bash -l {0} 40 | run: pip install . 41 | 42 | - name: Check installation files 43 | shell: bash -l {0} 44 | run: | 45 | test -d $CONDA_PREFIX/share/jupyter/nbextensions/jupyter-igv 46 | test -f $CONDA_PREFIX/share/jupyter/nbextensions/jupyter-igv/extension.js 47 | test -f $CONDA_PREFIX/share/jupyter/nbextensions/jupyter-igv/index.js 48 | test -d $CONDA_PREFIX/share/jupyter/labextensions/jupyter-igv 49 | test -f $CONDA_PREFIX/share/jupyter/labextensions/jupyter-igv/package.json 50 | 51 | - name: Import check 52 | shell: bash -l {0} 53 | run: python -c 'import ipyigv' 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.egg-info/ 2 | .ipynb_checkpoints/ 3 | dist/ 4 | build/ 5 | *.py[cod] 6 | node_modules/ 7 | js/package.json 8 | js/package-lock.json 9 | 10 | # Compiled javascript 11 | ipyigv/static/ 12 | 13 | # OS X 14 | .DS_Store 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Quantstack and ipycytoscape Contributors 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | 3. Neither the name of the copyright holder nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include ipyigv/static *.* 2 | include ipyigv.json 3 | 4 | include LICENSE 5 | include README.md 6 | include setup.py 7 | include pyproject.toml 8 | include pytest.ini 9 | include .coverage.rc 10 | 11 | # Javascript files 12 | graft js 13 | graft css 14 | prune **/node_modules 15 | prune coverage 16 | prune lib 17 | 18 | include package.json 19 | include webpack.config.js 20 | 21 | recursive-include ipyigv/labextension/* 22 | 23 | # Documentation 24 | graft docs 25 | exclude docs/\#* 26 | prune docs/build 27 | prune docs/gh-pages 28 | prune docs/dist 29 | 30 | # Examples 31 | graft examples 32 | 33 | # Tests 34 | graft tests 35 | prune tests/build 36 | 37 | # Javascript files 38 | graft js 39 | graft css 40 | prune **/node_modules 41 | prune coverage 42 | prune lib 43 | 44 | # Patterns to exclude from any directory 45 | global-exclude *~ 46 | global-exclude *.pyc 47 | global-exclude *.pyo 48 | global-exclude .git 49 | global-exclude .ipynb_checkpoints 50 | 51 | # Data files 52 | include ipyigv/public_genomes.json 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ipyigv 2 | 3 | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantStack/ipyigv/stable?filepath=notebooks/ipyigv.ipynb) 4 | 5 | A Jupyter wrapper for the igv.js library 6 | 7 | ## Installation 8 | 9 | To install use pip: 10 | 11 | pip install ipyigv 12 | 13 | To install with mamba: 14 | 15 | mamba install ipyigv -c conda-forge 16 | 17 | To install with conda: 18 | 19 | conda install ipyigv -c conda-forge 20 | 21 | To enable it in jupyter notebook 22 | 23 | jupyter nbextension enable --py --sys-prefix ipyigv 24 | 25 | To install for jupyterlab <=2 26 | 27 | jupyter labextension install @jupyter-widgets/jupyterlab-manager --no-build 28 | jupyter lab build 29 | 30 | 31 | ### For a development installation (requires npm), 32 | 33 | mamba install nodejs jupyterlab -c conda-forge 34 | 35 | git clone https://github.com//ipyigv.git 36 | cd ipyigv 37 | pip install -e . 38 | jupyter nbextension install --py --symlink --sys-prefix ipyigv 39 | jupyter nbextension enable --py --sys-prefix ipyigv 40 | jupyter labextension install js 41 | 42 | 43 | When actively developing your extension, build Jupyter Lab with the command: 44 | 45 | jupyter lab --watch 46 | 47 | This takes a minute or so to get started, but then automatically rebuilds JupyterLab when your javascript changes. 48 | 49 | Note on first `jupyter lab --watch`, you may need to touch a file to get Jupyter Lab to open. 50 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | - To release a new version of ipyigv on PyPI: 2 | 3 | * To release a new version is recommended to build ts dependencies with yarn. 4 | 5 | * Make sure to update the `pyproject.toml` with any new dependencies you include in this package. 6 | 7 | Update \_version.py 8 | git add the \_version.py file and git commit 9 | 10 | 11 | ``` 12 | python setup.py sdist upload 13 | python setup.py bdist_wheel upload 14 | git tag -a X.X.X -m 'comment' 15 | ``` 16 | 17 | git add and git commit 18 | git push 19 | git push --tags 20 | 21 | - To release a new version of ipyigv on NPM: 22 | 23 | Update `js/package.json` with new npm package version 24 | 25 | ``` 26 | # clean out the `dist` and `node_modules` directories 27 | git clean -fdx 28 | yarn install 29 | yarn publish 30 | ``` 31 | -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: ipyigv 2 | channels: 3 | - conda-forge 4 | dependencies: 5 | - ipyigv 6 | -------------------------------------------------------------------------------- /ipyigv/__init__.py: -------------------------------------------------------------------------------- 1 | from ._version import version_info, __version__ 2 | 3 | from .ipyigv import * 4 | 5 | def _jupyter_nbextension_paths(): 6 | """Called by Jupyter Notebook Server to detect if it is a valid nbextension and 7 | to install the widget 8 | 9 | Returns 10 | ======= 11 | section: The section of the Jupyter Notebook Server to change. 12 | Must be 'notebook' for widget extensions 13 | src: Source directory name to copy files from. Webpack outputs generated files 14 | into this directory and Jupyter Notebook copies from this directory during 15 | widget installation 16 | dest: Destination directory name to install widget files to. Jupyter Notebook copies 17 | from `src` directory into /nbextensions/ directory 18 | during widget installation 19 | require: Path to importable AMD Javascript module inside the 20 | /nbextensions/ directory 21 | """ 22 | return [{ 23 | 'section': 'notebook', 24 | 'src': 'static', 25 | 'dest': 'jupyter-igv', 26 | 'require': 'jupyter-igv/extension' 27 | }] 28 | -------------------------------------------------------------------------------- /ipyigv/_version.py: -------------------------------------------------------------------------------- 1 | # Module version 2 | version_info = (0, 1, 9) 3 | 4 | # Module version accessible using ipyigv.__version__ 5 | __version__ = '%s.%s.%s'%(version_info[0], version_info[1], version_info[2]) 6 | 7 | 8 | # Frontend version 9 | EXTENSION_VERSION = '^0.1.7' 10 | -------------------------------------------------------------------------------- /ipyigv/ipyigv.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from ipywidgets import DOMWidget, Output, Widget, register, widget_serialization 4 | from ipywidgets.widgets.trait_types import InstanceDict 5 | 6 | from traitlets import Unicode, Int, List, Instance, Bool, validate, TraitError 7 | from traitlets.utils.bunch import Bunch 8 | 9 | from .options import * 10 | 11 | from ._version import EXTENSION_VERSION 12 | 13 | PUBLIC_GENOMES_FILE = os.path.join(os.path.dirname(__file__), 'public_genomes.json') 14 | PUBLIC_GENOMES = Bunch({v['id']: v for v in json.load(open(PUBLIC_GENOMES_FILE, 'r')) } ) 15 | 16 | 17 | @register 18 | class IgvBrowser(DOMWidget): 19 | """An IGV browser widget.""" 20 | 21 | def __init__(self, **kwargs): 22 | super().__init__(**kwargs) 23 | self.on_msg(self._custom_message_handler) 24 | 25 | out = Output() 26 | 27 | _view_name = Unicode('IgvBrowser').tag(sync=True) 28 | _model_name = Unicode('IgvModel').tag(sync=True) 29 | _view_module = Unicode('jupyter-igv').tag(sync=True) 30 | _model_module = Unicode('jupyter-igv').tag(sync=True) 31 | _view_module_version = Unicode(EXTENSION_VERSION).tag(sync=True) 32 | _model_module_version = Unicode(EXTENSION_VERSION).tag(sync=True) 33 | 34 | # Widget-specific property. 35 | # Widget properties are defined as traitlets. Any property tagged with `sync=True` 36 | # is automatically synced to the frontend *any* time it changes in Python. 37 | # It is synced back to Python from the frontend *any* time the model is touched. 38 | genome = InstanceDict(ReferenceGenome).tag(sync=True, **widget_serialization) 39 | tracks = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) 40 | doubleClickDelay = Int(default_value=500).tag(sync=True) 41 | flanking = Int(default_value=1000).tag(sync=True) 42 | genomeList = Unicode(allow_none=True).tag(sync=True, **widget_serialization) # optional URL 43 | locus = (Unicode() | List(Unicode())).tag(sync=True, **widget_serialization) 44 | minimumBases = Int(default_value=40).tag(sync=True) 45 | queryParametersSupported = Bool(default=False).tag(sync=True) 46 | search = InstanceDict(SearchService, allow_none=True).tag(sync=True, **widget_serialization) 47 | showAllChromosomes = Bool(default_value=True).tag(sync=True) 48 | showAllChromosomeWidget = Bool(default_value=True).tag(sync=True) 49 | showNavigation = Bool(default_value=True).tag(sync=True) 50 | showSVGButton = Bool(default_value=False).tag(sync=True) 51 | showRuler = Bool(default_value=True).tag(sync=True) 52 | showCenterGuide = Bool(default_value=False).tag(sync=True) 53 | # trackDefaults = # missing documentation 54 | roi = List(InstanceDict(AnnotationTrack)).tag(sync=True, **widget_serialization) # regions of interest 55 | oauthToken = Unicode(allow_none = True).tag(sync=True) 56 | apiKey = Unicode(allow_none = True).tag(sync=True) 57 | clientId = Unicode(allow_none = True).tag(sync=True) 58 | 59 | def add_track(self, track): 60 | # List subscript does not work for empty List, so handling this case manually. 61 | if len(self.tracks) == 0: 62 | self.tracks = [track] 63 | else: 64 | self.tracks = self.tracks[:] + [track] 65 | 66 | def remove_track(self, track): 67 | self.tracks = [t for t in self.tracks if t != track] 68 | 69 | def add_roi(self, roi): 70 | # List subscript does not work for empty List, so handling this case manually. 71 | if len(self.roi) == 0: 72 | self.roi = [roi] 73 | else: 74 | self.roi = self.roi[:] + [roi] 75 | 76 | def remove_all_roi(self): 77 | self.roi = [] 78 | 79 | def search(self, symbol): 80 | self.send({"type": "search", "symbol": symbol}) 81 | print("Search completed. Check the widget instance for results.") 82 | 83 | def dump_json(self): 84 | print("Dumping browser configuration to browser.out") 85 | self.send({"type": "dump_json"}) 86 | 87 | @out.capture() 88 | def _custom_message_handler(self, _, content, buffers): 89 | if content.get('event', '') == 'return_json': 90 | self._return_json_handler(content) 91 | 92 | @out.capture() 93 | def _return_json_handler(self, content): 94 | print (content['json']) 95 | 96 | -------------------------------------------------------------------------------- /ipyigv/options.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from urllib.parse import urlparse 4 | 5 | from traitlets import Float, Unicode, Int, List, Instance, Bool, Dict, HasTraits 6 | 7 | from ipywidgets import Widget, register, widget_serialization 8 | from ipywidgets.widgets.trait_types import Color, InstanceDict 9 | from ipywidgets.widgets import widget 10 | 11 | from ._version import EXTENSION_VERSION 12 | 13 | 14 | # NB '.txt' considered annotation as it is used in the public genomes. But not as per the doc. 15 | TRACK_FILE_TYPES = { 16 | 'annotation': [ 17 | '.txt', '.bed', '.gff', '.gff3', '.gtf', '.genePred', '.genePredExt', 18 | '.peaks', '.narrowPeak', '.broadPeak', '.bigBed', '.bedpe' 19 | ], 20 | 'wig': ['.wig', '.bigWig', '.bedGraph'], 21 | 'alignment': ['.bam'], 22 | 'variant': ['.vcf'], 23 | 'seg': ['.seg'], 24 | 'spliceJunctions': ['.bed'], 25 | 'gwas': ['.gwas', '.bed'], 26 | 'interaction': ['.bedpe'], 27 | } 28 | 29 | 30 | class FieldColors(HasTraits): 31 | field = Unicode() 32 | palette = Dict(key_trait=Unicode, value_trait=Instance(Color)) 33 | 34 | 35 | class SortOption(HasTraits): 36 | chr = Unicode() # chromosone name 37 | position = Int() # genomic position 38 | option = Unicode() # 'BASE', 'STRAND', 'INSERT_SIZE', 'MATE_CHR', 'MQ', 'TAG' 39 | tag = Unicode () # doc not clear 40 | direction = Unicode("ASC") # 'ASC' for ascending, 'DESC' for descending 41 | 42 | 43 | class SortOrder(HasTraits): 44 | chr = Unicode() # chromosone name 45 | direction = Unicode("ASC") # 'ASC' for ascending, 'DESC' for descending 46 | start = Int() 47 | end = Int() 48 | 49 | 50 | @register 51 | class Track(Widget): 52 | """ 53 | A class reflecting the common fields of a track as per igv documentation. 54 | https://github.com/igvteam/igv.js/wiki/Tracks-2.0 55 | 56 | If a Track type is not inferable a generic Track will be instantiated. 57 | """ 58 | 59 | _view_name = Unicode('TrackView').tag(sync=True) 60 | _model_name = Unicode('TrackModel').tag(sync=True) 61 | _view_module = Unicode('jupyter-igv').tag(sync=True) 62 | _model_module = Unicode('jupyter-igv').tag(sync=True) 63 | _view_module_version = Unicode(EXTENSION_VERSION).tag(sync=True) 64 | _model_module_version = Unicode(EXTENSION_VERSION).tag(sync=True) 65 | 66 | def __new__(cls, **kwargs): 67 | if cls is Track: 68 | # we must infer the type to instantiate the right Track type 69 | trackType = kwargs.get('type', None) 70 | if trackType is None: 71 | # then type is inferred from the file extension 72 | url = kwargs.get('url') 73 | path = urlparse(url).path 74 | filename, filetype = os.path.splitext(path) 75 | if filetype == '.gz': # some files might be compressed 76 | innerfilename, innerfiletype = os.path.splitext(filename) 77 | filetype = innerfiletype 78 | for k, v in TRACK_FILE_TYPES.items(): 79 | if filetype in v: 80 | trackType = k 81 | break 82 | if trackType == 'annotation': 83 | return super(Track, cls).__new__(AnnotationTrack) 84 | elif trackType == 'alignment': 85 | return super(Track, cls).__new__(AlignmentTrack) 86 | elif trackType == 'variant': 87 | return super(Track, cls).__new__(VariantTrack) 88 | elif trackType == 'wig': 89 | return super(Track, cls).__new__(WigTrack) 90 | elif trackType == 'seg': 91 | return super(Track, cls).__new__(SegTrack) 92 | elif trackType == 'spliceJunctions': 93 | return super(Track, cls).__new__(SpliceJunctionsTrack) 94 | elif trackType == 'gwas': 95 | return super(Track, cls).__new__(GwassTrack) 96 | elif trackType == 'interation': 97 | return super(Track, cls).__new__(InteractionTrack) 98 | else: 99 | return super(Track, cls).__new__(cls) 100 | else: 101 | return super(Track, cls).__new__(cls) 102 | 103 | # These fields are common to all Track types 104 | sourceType = Unicode(default_value='file').tag(sync=True) # 105 | format = Unicode().tag(sync=True) # missing documentation 106 | name = Unicode().tag(sync=True) 107 | url = Unicode().tag(sync=True) 108 | indexURL = Unicode().tag(sync=True) 109 | indexed = Bool(default_value=False).tag(sync=True) 110 | order = Int().tag(sync=True) 111 | color = Color().tag(sync=True).tag(sync=True) 112 | height = Int(default_value=50).tag(sync=True) 113 | autoHeight = Bool(default_value=False).tag(sync=True) 114 | minHeight = Int(default_value=50).tag(sync=True) 115 | maxHeight = Int(default_value=500).tag(sync=True) 116 | # visibilityWindow = # missing documentation 117 | removable = Bool(default_value=True).tag(sync=True) 118 | headers = Dict().tag(sync=True) 119 | oauthToken = Unicode(allow_none = True).tag(sync=True) 120 | 121 | 122 | @register 123 | class AnnotationTrack(Track): 124 | """ 125 | AnnotationTrack as described at: 126 | https://github.com/igvteam/igv.js/wiki/Annotation-Track 127 | """ 128 | 129 | type = Unicode('annotation', read_only=True).tag(sync=True) 130 | displayMode = Unicode(default_value = 'COLLAPSED').tag(sync=True) 131 | expandedRowHeight = Int (default_value = 30).tag(sync=True) 132 | squishedRowHeight = Int (default_value = 15).tag(sync=True) 133 | nameField = Unicode(default_value = 'Name').tag(sync=True) 134 | maxRows = Int (default_value = 500).tag(sync=True) 135 | searchable = Bool(default_value=False).tag(sync=True) 136 | filterTypes = List(Unicode, default_value=['chromosone', 'gene']).tag(sync=True, **widget_serialization) 137 | color = Color("rgb(0,0,150)").tag(sync=True) 138 | altColor = Color("rgb(0,0,150)").tag(sync=True) 139 | colorBy = Instance(FieldColors, allow_none=True).tag(sync=True, **widget_serialization) 140 | roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) # regions of interest 141 | 142 | 143 | @register 144 | class AlignmentTrack(Track): 145 | """ 146 | AlignmentTrack as described at: 147 | https://github.com/igvteam/igv.js/wiki/Alignment-Track 148 | """ 149 | 150 | type = Unicode('alignment', read_only=True).tag(sync=True) 151 | viewAsPairs = Bool(default_value=False).tag(sync=True) 152 | pairsSupported = Bool(default_value=True).tag(sync=True) 153 | coverageColor = Color(default_value="rgb(150, 150, 150)").tag(sync=True, **widget_serialization) # default: rgb(150, 150, 150) 154 | color = Color(default_value="rgb(170, 170, 170)").tag(sync=True, **widget_serialization) # default: rgb(170, 170, 170) 155 | deletionColor = Color(default_value="black").tag(sync=True, **widget_serialization) 156 | skippedColor = Color(default_value="rgb(150, 170, 170)").tag(sync=True, **widget_serialization) # default: rgb(150, 170, 170) 157 | insertionColor = Color(default_value="rgb(138, 94, 161)").tag(sync=True, **widget_serialization) # default: rgb(138, 94, 161) 158 | negStrandColor = Color(default_value="rgba(150, 150, 230, 0.75)").tag(sync=True, **widget_serialization) # default: rgba(150, 150, 230, 0.75) 159 | posStrandColor = Color(default_value="rgba(230, 150, 150, 0.75)").tag(sync=True, **widget_serialization) # default: rgb(138, 94, 161) 160 | # pairConnectorColor = Instance(Color, default_value="alignmentColor") # default: doc not clear 161 | colorBy = Unicode("none").tag(sync=True) # "none", "strand", "firstOfPairStrand", or "tag" 162 | colorByTag = Unicode().tag(sync=True) # TODO - doc not clear 163 | bamColorTag = Unicode("YC").tag(sync=True) # TODO - doc not clear 164 | samplingWindowSize = Int(100).tag(sync=True) 165 | samplingDepth = Int(100).tag(sync=True) 166 | alignmentRowHeight = Int(14).tag(sync=True) 167 | readgroup = Unicode("RG").tag(sync=True) 168 | sortOption = Instance(SortOption, allow_none=True).tag(sync=True, **widget_serialization) 169 | showSoftClips = Bool(False).tag(sync=True) 170 | showMismatches = Bool(True).tag(sync=True) 171 | 172 | # Paired-end and mate-pair coloring options. 173 | pairOrientation = Unicode(allow_none=True).tag(sync=True, **widget_serialization) # ff, fr, or rf 174 | minFragmentLength = Int(allow_none=True).tag(sync=True, **widget_serialization) 175 | maxFragmentLength = Int(allow_none=True).tag(sync=True, **widget_serialization) 176 | 177 | roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) # regions of interest 178 | 179 | 180 | @register 181 | class VariantTrack(Track): 182 | """ 183 | VariantTrack as described at: 184 | https://github.com/igvteam/igv.js/wiki/Variant-Track 185 | """ 186 | 187 | type = Unicode('variant', read_only=True).tag(sync=True) 188 | displayMode = Unicode('EXPANDED').tag(sync=True) 189 | noCallColor = Color("rgb(250, 250, 250)").tag(sync=True) 190 | homvarColor = Color("rgb(17,248,254)").tag(sync=True) 191 | hetvarColor = Color("rgb(34,12,253)").tag(sync=True) 192 | homrefColor = Color("rgb(200, 200, 200)").tag(sync=True) 193 | squishedCallHeight = Int(1).tag(sync=True) 194 | expandedCallHeight = Int(10).tag(sync=True) 195 | 196 | roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) # regions of interest 197 | 198 | 199 | class Guideline(HasTraits): 200 | color = Color().tag(sync=True) 201 | dotted = Bool().tag(sync=True) 202 | y = Int().tag(sync=True) 203 | 204 | 205 | @register 206 | class WigTrack(Track): 207 | """ 208 | WigTrack as described at: 209 | https://github.com/igvteam/igv.js/wiki/Wig-Track 210 | """ 211 | 212 | type = Unicode('wig', read_only=True).tag(sync=True) 213 | autoscale = Bool(True).tag(sync=True) 214 | autoscaleGroup = Unicode(allow_none=True).tag(sync=True, **widget_serialization) 215 | min = Int(0).tag(sync=True) 216 | max = Int(allow_none=True).tag(sync=True, **widget_serialization) 217 | color = Color(default_value="rgb(150, 150, 150)").tag(sync=True) 218 | altColor = Color(allow_none=True).tag(sync=True, **widget_serialization) 219 | guideLines = List(trait=Instance(Guideline), allow_none=True).tag(sync=True, **widget_serialization) 220 | 221 | roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) # regions of interest 222 | 223 | 224 | @register 225 | class SegTrack(Track): 226 | """ 227 | SegTrack Track as described at: 228 | https://github.com/igvteam/igv.js/wiki/Seg-Track 229 | """ 230 | 231 | type = Unicode('seg', read_only=True).tag(sync=True) 232 | isLog = Bool(allow_none=True).tag(sync=True, **widget_serialization) 233 | displayMode = Unicode("EXPANDED").tag(sync=True) # "EXPANDED", "SQUISHED", or "FILL" 234 | sort = InstanceDict(SortOrder).tag(sync=True, **widget_serialization) 235 | 236 | roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) # regions of interest 237 | 238 | 239 | @register 240 | class SpliceJunctionsTrack(Track): 241 | """ 242 | SpliceJunctionsTrack as described at: 243 | https://github.com/igvteam/igv.js/wiki/SpliceJunctions 244 | """ 245 | 246 | type = Unicode('spliceJunctions', read_only=True).tag(sync=True) 247 | # Display Options 248 | colorBy = Unicode('numUniqueReads').tag(sync=True) # "numUniqueReads", "numReads", "isAnnotatedJunction", "strand", "motif" 249 | colorByNumReadsThreshold = Int(5).tag(sync=True) 250 | thicknessBasedOn = Unicode('numUniqueReads').tag(sync=True) # "numUniqueReads", "numReads", "isAnnotatedJunction" 251 | bounceHeightBasedOn = Unicode('random').tag(sync=True) # "random", "distance", "thickness" 252 | labelUniqueReadCount = Bool(True).tag(sync=True) 253 | labelMultiMappedReadCount = Bool(True).tag(sync=True) 254 | labelTotalReadCount = Bool(False).tag(sync=True) 255 | labelMotif = Bool(False).tag(sync=True) 256 | labelAnnotatedJunction = Unicode(allow_none=True).tag(sync=True, **widget_serialization) 257 | 258 | # Filtering Options 259 | minUniquelyMappedReads = Int(0).tag(sync=True) 260 | minTotalReads = Int(0).tag(sync=True) 261 | maxFractionMultiMappedReads = Int(1).tag(sync=True) 262 | minSplicedAlignmentOverhang = Int(0).tag(sync=True) 263 | hideStrand = Unicode(allow_none=True).tag(sync=True, **widget_serialization) # None, "+" or "-" 264 | hideAnnotatedJunctions = Bool(False).tag(sync=True) 265 | hideUnannotatedJunctions = Bool(False).tag(sync=True) 266 | hideMotifs = List(Unicode).tag(sync=True, **widget_serialization) 267 | 268 | roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) # regions of interest 269 | 270 | 271 | @register 272 | class GwasTrack (Track): 273 | """ 274 | GwasTrack as described at: 275 | https://github.com/igvteam/igv.js/wiki/GWAS 276 | """ 277 | 278 | type = Unicode('gwas', read_only=True).tag(sync=True) 279 | min = Int(0).tag(sync=True) 280 | max = Int(25).tag(sync=True) 281 | # format = Unicode().tag(sync=True) # 'bed' or 'gwas' - format is already in Track -> validation only 282 | posteriorProbability = Bool(False).tag(sync=True) 283 | dotSize = Int(3).tag(sync=True) 284 | columns = Dict(key_trait=Unicode, value_trait=Int, allow_none=True).tag(sync=True, **widget_serialization) 285 | 286 | roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) # regions of interest 287 | 288 | 289 | @register 290 | class InteractionTrack (Track): 291 | """ 292 | InteractionTrack as described at: 293 | https://github.com/igvteam/igv.js/wiki/Interaction 294 | """ 295 | 296 | type = Unicode('interaction', read_only=True).tag(sync=True) 297 | arcOrientation = Bool(True).tag(sync=True) 298 | thickness = Int(2).tag(sync=True) 299 | 300 | roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) # regions of interest 301 | 302 | 303 | class Exon(HasTraits): 304 | start = Int() 305 | end = Int() 306 | cdStart = Int() 307 | cdEnd = Int() 308 | utr = Bool() 309 | 310 | 311 | class TrackFeature(HasTraits): 312 | chr = Unicode() 313 | start = Int() 314 | end = Int() 315 | name = Unicode() 316 | score = Float() 317 | strand = Unicode() 318 | cdStart = Int() 319 | cdEnd = Int() 320 | color = Instance(Color) 321 | exons = List(trait=Instance(Exon)) 322 | 323 | 324 | @register 325 | class ReferenceGenome(Widget): 326 | """ 327 | A class reflecting a reference genome as per IGV documentation. 328 | https://github.com/igvteam/igv.js/wiki/Reference-Genome 329 | """ 330 | 331 | _view_name = Unicode('ReferenceGenomeView').tag(sync=True) 332 | _model_name = Unicode('ReferenceGenomeModel').tag(sync=True) 333 | _view_module = Unicode('jupyter-igv').tag(sync=True) 334 | _model_module = Unicode('jupyter-igv').tag(sync=True) 335 | _view_module_version = Unicode(EXTENSION_VERSION).tag(sync=True) 336 | _model_module_version = Unicode(EXTENSION_VERSION).tag(sync=True) 337 | 338 | id = Unicode(allow_none=True).tag(sync=True) 339 | name = Unicode(allow_none=True).tag(sync=True) 340 | fastaURL = Unicode().tag(sync=True) 341 | indexURL = Unicode(allow_none=True).tag(sync=True) 342 | cytobandURL = Unicode(allow_none=True).tag(sync=True) 343 | aliasURL = Unicode(allow_none=True).tag(sync=True) 344 | indexed = Bool(default_value=False).tag(sync=True) 345 | tracks = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) 346 | chromosomeOrder = Unicode(allow_none=True).tag(sync=True) 347 | headers = Dict().tag(sync=True) 348 | wholeGenomeView = Bool(default_value=True).tag(sync=True) 349 | 350 | 351 | @register 352 | class SearchService(Widget): 353 | url = Unicode() 354 | resultsField = Unicode() 355 | coords = Int(default_value=1) 356 | chromosomeField = Unicode(default_value='chromosome') 357 | startField = Unicode(default_value='start') 358 | endField = Unicode(default_value='end', allow_none=True) 359 | -------------------------------------------------------------------------------- /ipyigv/public_genomes.json: -------------------------------------------------------------------------------- 1 | [{"id":"hg38","name":"Human (GRCh38/hg38)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg38/hg38.fa","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg38/hg38.fa.fai","cytobandURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/hg38/annotations/cytoBandIdeo.txt.gz","tracks":[{"name":"Refseq Genes","format":"refgene","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/hg38/refGene.txt.gz","indexed":false,"visibilityWindow":-1,"removable":false,"order":1000000}]},{"id":"hg19","name":"Human (CRCh37/hg19)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg19/hg19.fasta","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg19/hg19.fasta.fai","cytobandURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg19/cytoBand.txt","tracks":[{"name":"Refseq Genes","format":"refgene","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/hg19/refGene.txt.gz","indexed":false,"visibilityWindow":-1,"removable":false,"order":1000000}]},{"id":"hg18","name":"Human (hg18)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg18/hg18.fasta","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg18/hg18.fasta.fai","cytobandURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/hg18/cytoBandIdeo.txt.gz","tracks":[{"name":"Refseq Genes","format":"refgene","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/hg18/refGene.txt.gz","indexed":false,"visibilityWindow":-1,"removable":false,"order":1000000}]},{"id":"mm10","name":"Mouse (GRCm38/mm10)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/mm10/mm10.fa","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/mm10/mm10.fa.fai","cytobandURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/annotations/mm10/cytoBandIdeo.txt.gz","order":1000000,"tracks":[{"name":"Refseq Genes","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/mm10/refGene.txt.gz","indexed":false,"order":1000000,"removable":false,"visibilityWindow":-1,"supportsWholeGenome":false}]},{"id":"mm9","name":"Mouse (NCBI37/mm9)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/mm9/mm9.fasta","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/mm9/mm9.fasta.fai","cytobandURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/mm9/cytoBandIdeo.txt.gz","order":1000000,"tracks":[{"name":"Refseq Genes","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/mm9/refGene.txt.gz","indexed":false,"order":1000000,"removable":false,"visibilityWindow":-1,"supportsWholeGenome":false}]},{"id":"rn6","name":"Rat (RGCS 6.0/rn6)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/rn6/rn6.fa","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/rn6/rn6.fa.fai","cytobandURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/rn6/cytoBand.txt.gz","order":1000000,"tracks":[{"name":"Refseq Genes","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/rn6/refGene.txt.gz","indexed":false,"order":1000000,"removable":false,"supportsWholeGenome":false,"visibilityWindow":-1}]},{"id":"gorGor4","name":"Gorilla (gorGor4.1/gorGor4)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/gorGor4/gorGor4.fa","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/gorGor4/gorGor4.fa.fai","cytobandURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/gorGor4/cytoBandIdeo.txt.gz","chromosomeOrder":"chr1,chr2A,chr2B,chr3,chr4,chr5,chr6,chr7,chr8,chr9,chr10,chr11,chr12,chr13,chr14,chr15,chr16,chr17,chr18,chr19,chr20,chr21,chr22,chrX","tracks":[{"name":"Refseq Genes","format":"refgene","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/gorGor4/refGene.txt.gz","indexed":false,"order":1000000,"removable":false,"visibilityWindow":-1}]},{"id":"panTro4","name":" Chimp (SAC 2.1.4/panTro4)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/panTro4/panTro4.fa","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/panTro4/panTro4.fa.fai","cytobandURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/panTro4/cytoBandIdeo.txt.gz","chromosomeOrder":"chr1,chr2A,chr2B,chr3,chr4,chr5,chr6,chr7,chr8,chr9,chr10,chr11,chr12,chr13,chr14,chr15,chr16,chr17,chr18,chr19,chr20,chr21,chr22,chrX,chrY","tracks":[{"name":"Refseq Genes","format":"refgene","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/panTro4/refGene.txt.gz","indexed":false,"removable":false,"order":1000000,"visibilityWindow":-1}]},{"id":"panPan2","name":"Bonobo (MPI-EVA panpan1.1/panPan2)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/panPan2/panPan2.fa","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/panPan2/panPan2.fa.fai","cytobandURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/panPan2/cytoBandIdeo.txt.gz","chromosomeOrder":"chr1,chr2A,chr2B,chr3,chr4,chr5,chr6,chr7,chr8,chr9,chr10,chr11,chr12,chr13,chr14,chr15,chr16,chr17,chr18,chr19,chr20,chr21,chr22,chrX","tracks":[{"name":"Refseq Genes","format":"refgene","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/panPan2/refGene.txt.gz","indexed":false,"removable":false,"order":1000000,"visibilityWindow":-1}]},{"id":"canFam3","name":"Dog (Broad CanFam3.1/canFam3)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/canFam3/canFam3.fa","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/canFam3/canFam3.fa.fai","cytobandURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/canFam3/cytoBandIdeo.txt.gz","tracks":[{"name":"Refseq Genes","format":"refgene","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/canFam3/refGene.txt.gz","indexed":false,"removable":false,"order":1000000,"visibilityWindow":-1}]},{"id":"bosTau8","name":"Cow (UMD_3.1.1/bosTau8)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/bosTau8/bosTau8.fa","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/bosTau8/bosTau8.fa.fai","cytobandURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/bosTau8/cytoBandIdeo.txt.gz","tracks":[{"name":"Refseq Genes","format":"refgene","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/bosTau8/refGene.txt.gz","indexed":false,"removable":false,"order":1000000,"visibilityWindow":-1}]},{"id":"bosTau9","name":"Cow (ARS-UCD1.2/bosTau9)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/bosTau9/bosTau9.fa","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/bosTau9/bosTau9.fa.fai","cytobandURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/bosTau9/cytoBandIdeo.txt.gz","tracks":[{"name":"Refseq Genes","format":"refgene","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/bosTau9/refGene.txt.gz","indexed":false,"removable":false,"order":1000000,"visibilityWindow":-1}]},{"id":"susScr11","name":"Pig (SGSC Sscrofa11.1/susScr11)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/susScr11/susScr11.fa","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/susScr11/susScr11.fa.fai","cytobandURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/susScr11/cytoBandIdeo.txt.gz","tracks":[{"name":"Refseq Genes","format":"refgene","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/susScr11/refGene.txt.gz","indexed":false,"removable":false,"order":1000000,"visibilityWindow":-1}]},{"id":"danRer11","name":"Zebrafish (GRCZ11/danRer11)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/danRer11/danRer11.fa","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/danRer11/danRer11.fa.fai","cytobandURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/danRer11/cytoBandIdeo.txt.gz","aliasURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/danRer11/chromAlias.txt.gz","tracks":[{"name":"Refseq Genes","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/danRer11/refGene.txt.gz","indexed":false,"order":1000000,"removable":false,"supportsWholeGenome":false,"visibilityWindow":-1}]},{"id":"danRer10","name":"Zebrafish (GRCZ10/danRer10)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/danRer10/danRer10.fa","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/danRer10/danRer10.fa.fai","cytobandURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/danRer10/cytoBandIdeo.txt.gz","order":1000000,"tracks":[{"name":"Refseq Genes","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/danRer10/refGene.txt.gz","indexed":false,"order":1000000,"removable":false,"supportsWholeGenome":false,"visibilityWindow":-1}]},{"id":"ce11","name":"C. elegans (ce11)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/ce11/ce11.fa","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/ce11/ce11.fa.fai","cytobandURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/ce11/cytoBandIdeo.txt.gz","tracks":[{"name":"Refseq Genes","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/ce11/refGene.txt.gz","indexed":false,"order":1000000,"removable":false,"supportsWholeGenome":false,"visibilityWindow":-1}]},{"id":"dm6","name":"D. melanogaster (dm6)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/dm6/dm6.fa","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/dm6/dm6.fa.fai","cytobandURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/dm6/cytoBandIdeo.txt.gz","tracks":[{"name":"Refseq Genes","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/dm6/refGene.txt.gz","indexed":false,"order":1000000,"removable":false,"supportsWholeGenome":false,"visibilityWindow":-1}]},{"id":"sacCer3","name":"S. cerevisiae (sacCer3)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/sacCer3/sacCer3.fa","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/sacCer3/sacCer3.fa.fai","tracks":[{"name":"Ensembl Genes","type":"annotation","format":"ensgene","displayMode":"EXPANDED","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/sacCer3/ensGene.txt.gz","indexed":false,"supportsWholeGenome":false}]},{"id":"ASM294v2","name":"S. pombe (ASM294v2)","fastaURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/S.pombe_ASM294v2/Schizosaccharomyces_pombe_all_chromosomes.fa","indexURL":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/S.pombe_ASM294v2/Schizosaccharomyces_pombe_all_chromosomes.fa.fai","tracks":[{"name":"Pombase forward strand","type":"annotation","format":"gff3","displayMode":"EXPANDED","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/S.pombe_ASM294v2/Schizosaccharomyces_pombe_all_chromosomes.plus.gff3.gz","indexed":false,"supportsWholeGenome":true,"labelAllFeatures":true,"height":150,"color":"rgb(5,75,180)"},{"name":"Pombase reverse strand","type":"annotation","format":"gff3","displayMode":"EXPANDED","url":"https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/S.pombe_ASM294v2/Schizosaccharomyces_pombe_all_chromosomes.minus.gff3.gz","indexed":false,"supportsWholeGenome":true,"height":150,"color":"rgb(7,123,220)"}]},{"id":"ASM985889v3","name":"Sars-CoV-2 (ASM985889v3)","fastaURL":"https://s3.amazonaws.com/igv.org.genomes/covid_ASM985889v3/GCF_009858895.2_ASM985889v3_genomic.fna","indexURL":"https://s3.amazonaws.com/igv.org.genomes/covid_ASM985889v3/GCF_009858895.2_ASM985889v3_genomic.fna.fai","order":1000000,"tracks":[{"name":"Annotations","url":"https://s3.amazonaws.com/igv.org.genomes/covid_ASM985889v3/GCF_009858895.2_ASM985889v3_genomic.gff.gz","displayMode":"EXPANDED","nameField":"gene","height":150}]}] -------------------------------------------------------------------------------- /ipyigv/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jupyter-widgets-contrib/ipyigv/b78614ad42c7cc12b199e29b660dea2a155d5264/ipyigv/tests/__init__.py -------------------------------------------------------------------------------- /ipyigv/tests/test.py: -------------------------------------------------------------------------------- 1 | import ipyigv 2 | -------------------------------------------------------------------------------- /js/css/.widget.css.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jupyter-widgets-contrib/ipyigv/b78614ad42c7cc12b199e29b660dea2a155d5264/js/css/.widget.css.swp -------------------------------------------------------------------------------- /js/css/widget.css: -------------------------------------------------------------------------------- 1 | .igv-track { 2 | width: 100%; 3 | resize: both; 4 | } 5 | -------------------------------------------------------------------------------- /js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jupyter-igv", 3 | "version": "0.1.9", 4 | "description": "A Jupyter wrapper for the igv.js library", 5 | "author": "QuantStack", 6 | "main": "src/index.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/QuantStack/ipyigv" 10 | }, 11 | "keywords": [ 12 | "jupyter", 13 | "widgets", 14 | "ipython", 15 | "ipywidgets", 16 | "jupyterlab-extension" 17 | ], 18 | "files": [ 19 | "src/**/*.js", 20 | "css/*.css", 21 | "dist/*.js" 22 | ], 23 | "scripts": { 24 | "clean": "rimraf dist/", 25 | "prepublish": "webpack", 26 | "build": "webpack && yarn run build:labextension", 27 | "build:labextension": "jupyter labextension build .", 28 | "watch": "webpack --watch --mode=development", 29 | "test": "echo \"Error: no test specified\" && exit 1" 30 | }, 31 | "dependencies": { 32 | "@jupyter-widgets/base": "^2 || ^3 || ^4.0.0", 33 | "igv": "^2.7.5", 34 | "lodash": "^4.17.4" 35 | }, 36 | "devDependencies": { 37 | "@jupyterlab/builder": "^3.0.0", 38 | "css-loader": "^5.0.1", 39 | "rimraf": "^2.6.1", 40 | "style-loader": "^2.0.0", 41 | "webpack": "^5", 42 | "webpack-cli": "^4.5.0" 43 | }, 44 | "jupyterlab": { 45 | "extension": "src/labplugin", 46 | "outputDir": "../ipyigv/labextension", 47 | "sharedPackages": { 48 | "@jupyter-widgets/base": { 49 | "bundled": false, 50 | "singleton": true 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /js/src/embed.js: -------------------------------------------------------------------------------- 1 | // Entry point for the unpkg bundle containing custom model definitions. 2 | // 3 | // It differs from the notebook bundle in that it does not need to define a 4 | // dynamic baseURL for the static assets and may load some css that would 5 | // already be loaded by the notebook otherwise. 6 | 7 | // Export widget models and views, and the npm package version number. 8 | module.exports = require('./ipyigv.js'); 9 | module.exports['version'] = require('../package.json').version; 10 | -------------------------------------------------------------------------------- /js/src/extension.js: -------------------------------------------------------------------------------- 1 | // This file contains the javascript that is run when the notebook is loaded. 2 | // It contains some requirejs configuration and the `load_ipython_extension` 3 | // which is required for any notebook extension. 4 | 5 | // Configure requirejs 6 | if (window.require) { 7 | window.require.config({ 8 | map: { 9 | "*" : { 10 | "jupyter-igv": "nbextensions/jupyter-igv/index", 11 | } 12 | } 13 | }); 14 | } 15 | 16 | // Export the required load_ipython_extension 17 | module.exports = { 18 | load_ipython_extension: function() {} 19 | }; 20 | -------------------------------------------------------------------------------- /js/src/index.js: -------------------------------------------------------------------------------- 1 | // Export widget models and views, and the npm package version number. 2 | module.exports = require('./ipyigv.js'); 3 | module.exports['version'] = require('../package.json').version; 4 | -------------------------------------------------------------------------------- /js/src/ipyigv.js: -------------------------------------------------------------------------------- 1 | import * as widgets from '@jupyter-widgets/base'; 2 | import * as _ from 'lodash'; 3 | import igv from 'igv/dist/igv.js'; 4 | import '../css/widget.css'; 5 | 6 | import { MODULE_NAME, MODULE_VERSION } from './version'; 7 | 8 | export class TrackModel extends widgets.WidgetModel { 9 | defaults () { 10 | return _.extend(super.defaults(), { 11 | _model_name : 'TrackModel', 12 | _view_name : 'TrackView', 13 | _model_module : MODULE_NAME, 14 | _view_module : MODULE_NAME, 15 | _model_module_version : MODULE_VERSION, 16 | _view_module_version : MODULE_VERSION, 17 | }); 18 | }; 19 | }; 20 | 21 | export class ReferenceGenomeModel extends widgets.WidgetModel { 22 | defaults () { 23 | return _.extend(super.defaults(), { 24 | _model_name : 'ReferenceGenomeModel', 25 | _view_name : 'ReferenceGenomeView', 26 | _model_module : MODULE_NAME, 27 | _view_module : MODULE_NAME, 28 | _model_module_version : MODULE_VERSION, 29 | _view_module_version : MODULE_VERSION, 30 | }); 31 | }; 32 | }; 33 | 34 | 35 | ReferenceGenomeModel.serializers = _.extend({ 36 | tracks: { deserialize: widgets.unpack_models } 37 | }, 38 | widgets.WidgetModel.serializers 39 | ) 40 | 41 | export class IgvModel extends widgets.DOMWidgetModel { 42 | defaults () { 43 | return _.extend(super.defaults(), { 44 | _model_name : 'IgvModel', 45 | _view_name : 'IgvBrowser', 46 | _model_module : MODULE_NAME, 47 | _view_module : MODULE_NAME, 48 | _model_module_version : MODULE_VERSION, 49 | _view_module_version : MODULE_VERSION, 50 | }); 51 | }; 52 | 53 | initialize(attributes, options) { 54 | super.initialize(attributes, options); 55 | this.on("msg:custom", this.custom_message_handler); 56 | }; 57 | 58 | custom_message_handler(msg) { 59 | console.log('custom_message_handler in model', msg); 60 | if (msg.type === 'dump_json') { 61 | this.trigger('return_json'); 62 | } 63 | else if (msg.type === 'search') { 64 | var symbol = msg.symbol 65 | this.trigger('search', symbol); 66 | } 67 | }; 68 | }; 69 | 70 | IgvModel.serializers = _.extend({ 71 | genome: { deserialize: widgets.unpack_models }, 72 | tracks: { deserialize: widgets.unpack_models }, 73 | roi: { deserialize: widgets.unpack_models }, 74 | }, 75 | widgets.DOMWidgetModel.serializers 76 | ) 77 | 78 | export class ReferenceGenomeView extends widgets.WidgetView { 79 | render () { 80 | super.render(); 81 | console.log("rendering ReferenceGenomeView"); 82 | } 83 | } 84 | 85 | export class TrackView extends widgets.WidgetView { 86 | render () { 87 | super.render(); 88 | console.log("rendering TrackView"); 89 | } 90 | } 91 | 92 | export class IgvBrowser extends widgets.DOMWidgetView { 93 | initialize(options) { 94 | super.initialize(options); 95 | this.tracks_initialized = true; 96 | this.browser = null; 97 | this.track_views = new widgets.ViewList(this.add_track_view, this.remove_track_view, this); 98 | console.log("configuring track_views"); 99 | this.track_views.update(this.model.get('tracks')); 100 | this.tracks_initialized = true; 101 | console.log("Done configuring track_views"); 102 | 103 | this.roi_views = new widgets.ViewList(this.add_roi_view, this.remove_roi_view, this); 104 | console.log("configuring roi_views"); 105 | this.roi_views.update(this.model.get('roi')); 106 | console.log("Done configuring roi_views") 107 | } 108 | 109 | render() { 110 | super.render(); 111 | 112 | var referenceGenome = this.model.get('genome'); 113 | var tracks = this.model.get('tracks'); 114 | var roi = this.model.get('roi'); 115 | var doubleClickDelay = this.model.get('doubleClickDelay'); 116 | var flanking = this.model.get('flanking'); 117 | var genomeList = this.model.get('genomeList'); 118 | var locus = this.model.get('locus'); 119 | var minimumBases = this.model.get('minimumBases'); 120 | var queryParametersSupported = this.model.get('queryParametersSupported'); 121 | var search = this.model.get('search'); 122 | var showAllChromosomes = this.model.get('showAllChromosomes'); 123 | var showAllChromosomeWidget = this.model.get('showAllChromosomeWidget'); 124 | var showNavigation = this.model.get('showNavigation'); 125 | var showSVGButton = this.model.get('showSVGButton'); 126 | var showRuler = this.model.get('showRuler'); 127 | var showCenterGuide = this.model.get('showCenterGuide'); 128 | var oauthToken = this.model.get('oauthToken'); 129 | var apiKey = this.model.get('apiKey'); 130 | var clientId = this.model.get('clientId'); 131 | 132 | var options = { 133 | reference: referenceGenome, 134 | tracks: tracks, 135 | roi: roi, 136 | doubleClickDelay: doubleClickDelay, 137 | flanking: flanking, 138 | genomeList: genomeList, 139 | locus: locus, 140 | minimumBases: minimumBases, 141 | queryParametersSupported: queryParametersSupported, 142 | showAllChromosomes:showAllChromosomes, 143 | showAllChromosomeWidget: showAllChromosomeWidget, 144 | showNavigation: showNavigation, 145 | showSVGButton: showSVGButton, 146 | showRuler: showRuler, 147 | showCenterGuide: showCenterGuide, 148 | }; 149 | 150 | if (search) { 151 | options['search']=search 152 | } 153 | if (oauthToken) { 154 | options['oauthToken']=oauthToken 155 | } 156 | if (apiKey) { 157 | options['apiKey']=apiKey 158 | } 159 | if (clientId) { 160 | options['clientId']=clientId 161 | } 162 | 163 | console.log("rendering browser", options); 164 | this.browser = igv.createBrowser(this.el, options) 165 | .then((browser) => { 166 | console.log("Created IGV browser with options ", options); 167 | browser.on('trackremoved', this.track_removed); 168 | browser.on('trackdragend', this.track_dragged); 169 | 170 | browser.on('locuschange', this.locus_changed); 171 | browser.on('trackclick', this.track_clicked); 172 | return browser; 173 | }); 174 | 175 | this.listenTo(this.model, 'change:genome', this.update_genome); 176 | this.listenTo(this.model, 'change:tracks', this.update_tracks); 177 | this.listenTo(this.model, 'change:roi', this.update_roi); 178 | this.listenTo(this.model, "return_json", this._return_json); 179 | this.listenTo(this.model, "search", this._search); 180 | 181 | } 182 | 183 | update_genome () { 184 | var genome = this.model.get('genome'); 185 | console.log('Updating browser reference with ', genome); 186 | this.browser.then((b) => { 187 | b.loadGenome(genome); 188 | }); 189 | } 190 | 191 | update_tracks () { 192 | console.log("update_tracks") 193 | if (this.tracks_initialized) { 194 | var tracks = this.model.get('tracks'); 195 | console.log('Updating tracks_views with ', tracks); 196 | this.track_views.update(tracks); 197 | } 198 | else { 199 | console.log ("Tracks not yet initialized - skipping"); 200 | } 201 | } 202 | 203 | add_track_view (child_model) { 204 | return this.create_child_view(child_model, {}).then(view => { 205 | console.log('add_track_view with child :', child_model); 206 | if (this.tracks_initialized) { 207 | return this.browser.then((browser) => { 208 | return browser.loadTrack(child_model.attributes).then((newTrack) => { 209 | console.log("new track loaded in browser: " , newTrack); 210 | view.igvTrack = newTrack 211 | return view; 212 | }); 213 | }); 214 | } else { 215 | console.log("track_view not yet initialized, skipping"); 216 | return view; 217 | } 218 | }); 219 | } 220 | 221 | remove_track_view (child_view) { 222 | console.log('removing Track from genome', child_view.igvTrack); 223 | 224 | if (!this.tracks_initialized) { 225 | console.log("track_view not yet initialized, skipping"); 226 | return; 227 | } 228 | var child = child_view 229 | this.browser.then(b => { 230 | //b.removeTrackByName(child_view.model.get("name")); 231 | if (child.igvTrack){ 232 | b.removeTrack(child.igvTrack); 233 | } 234 | else { 235 | b.removeTrackByName(child.model.get("name")); 236 | } 237 | }); 238 | } 239 | 240 | update_roi () { 241 | console.log("update_roi") 242 | var roi = this.model.get('roi'); 243 | console.log('Updating roi_views with ', roi); 244 | // the browser lets us only add ROI (one or several), or delete all ROI. (no unitary delete) 245 | if (roi == []) { 246 | console.log('removing Regions of Interest'); 247 | this.browser.then(b => { b.clearROIs(); }); 248 | } 249 | else { 250 | this.roi_views.update(roi); 251 | } 252 | } 253 | 254 | add_roi_view (child_model) { 255 | return this.create_child_view(child_model, {}).then(view => { 256 | console.log('add_roi_view with child view :', view); 257 | return this.browser.then((browser) => { 258 | return browser.loadROI(view.model.attributes).then((newROI) => { 259 | console.log("new roi loaded in browser: " , newROI); 260 | return view; 261 | }); 262 | }); 263 | }); 264 | } 265 | 266 | remove_all_roi_view (child_view) { 267 | console.log('Oops - removing one Region of Interest not supported - Ignoring'); 268 | } 269 | 270 | track_removed (tracks) { 271 | console.log('track removed', tracks); 272 | } 273 | 274 | track_dragged (arg) { 275 | console.log('track dragged', arg); 276 | } 277 | 278 | locus_changed (referenceFrame, label) { 279 | console.log('locus changed', referenceFrame, label); 280 | } 281 | 282 | track_clicked (track, popoverData) { 283 | console.log('track clicked', track, popoverData); 284 | } 285 | 286 | _return_json(event) { 287 | console.log('view._return_json', event); 288 | this.browser.then((browser)=> { 289 | var json = browser.toJSON() 290 | this.send({ event: 'return_json', json:json}); 291 | 292 | }); 293 | } 294 | 295 | _search(symbol) { 296 | console.log('view._search', symbol); 297 | var symbol = symbol 298 | this.browser.then((browser) => { 299 | browser.search(symbol); 300 | }); 301 | } 302 | } 303 | -------------------------------------------------------------------------------- /js/src/labplugin.js: -------------------------------------------------------------------------------- 1 | var plugin = require('./index'); 2 | var base = require('@jupyter-widgets/base'); 3 | 4 | module.exports = { 5 | id: 'jupyter-igv', 6 | requires: [base.IJupyterWidgetRegistry], 7 | activate: function(app, widgets) { 8 | widgets.registerWidget({ 9 | name: 'jupyter-igv', 10 | version: plugin.version, 11 | exports: plugin 12 | }); 13 | }, 14 | autoStart: true 15 | }; 16 | 17 | -------------------------------------------------------------------------------- /js/src/notebook.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Jupyter Development Team. 2 | // Distributed under the terms of the Modified BSD License. 3 | 4 | // Some static assets may be required by the custom widget javascript. The base 5 | // url for the notebook is not known at build time and is therefore computed 6 | // dynamically. 7 | __webpack_public_path__ = document.querySelector('body').getAttribute('data-base-url') + 'nbextensions/jupyter-igv/'; 8 | 9 | module.exports = require('./index.js'); 10 | -------------------------------------------------------------------------------- /js/src/version.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020, QuantStack and ipyigv Contributors 2 | // 3 | // Distributed under the terms of the Modified BSD License. 4 | // 5 | // The full license is in the file LICENSE, distributed with this software. 6 | 7 | const data = require('../package.json'); 8 | 9 | /** 10 | * The _model_module_version/_view_module_version this package implements. 11 | * 12 | * The html widget manager assumes that this is the same as the npm package 13 | * version number. 14 | */ 15 | export const MODULE_VERSION = data.version; 16 | 17 | /* 18 | * The current package name. 19 | */ 20 | export const MODULE_NAME = data.name; 21 | 22 | -------------------------------------------------------------------------------- /js/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var version = require('./package.json').version; 3 | 4 | var rules = [ 5 | { 6 | test: /\.css$/, 7 | use: ['style-loader', 'css-loader'] 8 | }, 9 | ]; 10 | 11 | module.exports = [ 12 | {// Notebook extension 13 | entry: './src/extension.js', 14 | output: { 15 | filename: 'extension.js', 16 | path: path.resolve(__dirname, '..', 'ipyigv', 'nbextension'), 17 | libraryTarget: 'amd' 18 | }, 19 | module: { 20 | rules: rules 21 | }, 22 | }, 23 | {// jupyter-igv bundle for the classic notebook 24 | entry: './src/notebook.js', 25 | output: { 26 | filename: 'index.js', 27 | path: path.resolve(__dirname, '..', 'ipyigv', 'nbextension'), 28 | libraryTarget: 'amd', 29 | publicPath: '', 30 | }, 31 | devtool: 'source-map', 32 | module: { 33 | rules: rules 34 | }, 35 | externals: ['@jupyter-widgets/base'], 36 | }, 37 | {// jupyter-igv bundle for unpkg 38 | entry: './src/embed.js', 39 | output: { 40 | filename: 'index.js', 41 | path: path.resolve(__dirname, 'dist'), 42 | libraryTarget: 'amd', 43 | publicPath: '', 44 | }, 45 | devtool: 'source-map', 46 | module: { 47 | rules: rules 48 | }, 49 | externals: ['@jupyter-widgets/base'], 50 | } 51 | ]; 52 | -------------------------------------------------------------------------------- /jupyter-igv.json: -------------------------------------------------------------------------------- 1 | { 2 | "load_extensions": { 3 | "jupyter-igv/extension": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /notebooks/ipyigv.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import ipyigv as igv\n", 10 | "from ipywidgets.widgets.trait_types import InstanceDict\n", 11 | "from ipyigv.options import ReferenceGenome, Track\n", 12 | "from ipywidgets import Output " 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "## Initializing the browser " 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 2, 25 | "metadata": {}, 26 | "outputs": [], 27 | "source": [ 28 | "genomeDict = igv.PUBLIC_GENOMES.hg38" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 3, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "genome = ReferenceGenome(**genomeDict)" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 4, 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [ 46 | "browser = igv.IgvBrowser(genome=genome)" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": 5, 52 | "metadata": {}, 53 | "outputs": [ 54 | { 55 | "data": { 56 | "application/vnd.jupyter.widget-view+json": { 57 | "model_id": "04a1528671b2420ca8ef1137cfba2e0f", 58 | "version_major": 2, 59 | "version_minor": 0 60 | }, 61 | "text/plain": [ 62 | "IgvBrowser(genome=ReferenceGenome(cytobandURL='https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/hg…" 63 | ] 64 | }, 65 | "metadata": {}, 66 | "output_type": "display_data" 67 | } 68 | ], 69 | "source": [ 70 | "browser" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": {}, 76 | "source": [ 77 | "## Adding or removing a track" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 6, 83 | "metadata": {}, 84 | "outputs": [], 85 | "source": [ 86 | "trackDict = {\n", 87 | " 'name': 'Refseq Genes',\n", 88 | " 'format': 'refgene',\n", 89 | " 'url': 'https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/hg38/refGene.txt.gz',\n", 90 | " 'indexed': False,\n", 91 | " 'visibilityWindow': -1,\n", 92 | " 'removable': False,\n", 93 | " 'order': 1000000\n", 94 | "}" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 7, 100 | "metadata": {}, 101 | "outputs": [], 102 | "source": [ 103 | "oneMoreTrack = Track(**trackDict)" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 8, 109 | "metadata": {}, 110 | "outputs": [], 111 | "source": [ 112 | "browser.add_track(oneMoreTrack)" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": 9, 118 | "metadata": {}, 119 | "outputs": [], 120 | "source": [ 121 | "browser.remove_track(oneMoreTrack)" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "metadata": {}, 127 | "source": [ 128 | "## Adding a Region of Interest" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 10, 134 | "metadata": {}, 135 | "outputs": [], 136 | "source": [ 137 | "roiDict = {\n", 138 | " 'name': 'ROI set 1',\n", 139 | " 'url': 'https://s3.amazonaws.com/igv.org.test/data/roi/roi_bed_1.bed',\n", 140 | " 'indexed': False,\n", 141 | " 'color': \"rgba(68, 134, 247, 0.25)\"\n", 142 | "}" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": 11, 148 | "metadata": {}, 149 | "outputs": [], 150 | "source": [ 151 | "roi = igv.options.AnnotationTrack(**roiDict)" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": 12, 157 | "metadata": {}, 158 | "outputs": [], 159 | "source": [ 160 | "browser.add_roi(roi)" 161 | ] 162 | }, 163 | { 164 | "cell_type": "markdown", 165 | "metadata": {}, 166 | "source": [ 167 | "## Searching" 168 | ] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": 13, 173 | "metadata": {}, 174 | "outputs": [ 175 | { 176 | "name": "stdout", 177 | "output_type": "stream", 178 | "text": [ 179 | "Search completed. Check the widget instance for results.\n" 180 | ] 181 | } 182 | ], 183 | "source": [ 184 | "browser.search('chr3:1-190,100,300')" 185 | ] 186 | }, 187 | { 188 | "cell_type": "markdown", 189 | "metadata": {}, 190 | "source": [ 191 | "## Getting the browser configuration\n", 192 | "We need to output the configuration in `browser.out`, which is an `Output` widget" 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "execution_count": 14, 198 | "metadata": {}, 199 | "outputs": [ 200 | { 201 | "name": "stdout", 202 | "output_type": "stream", 203 | "text": [ 204 | "Dumping browser configuration to browser.out\n" 205 | ] 206 | } 207 | ], 208 | "source": [ 209 | "browser.dump_json()" 210 | ] 211 | }, 212 | { 213 | "cell_type": "code", 214 | "execution_count": 15, 215 | "metadata": { 216 | "scrolled": true 217 | }, 218 | "outputs": [ 219 | { 220 | "data": { 221 | "application/vnd.jupyter.widget-view+json": { 222 | "model_id": "1de5607e0eef4a82af973d2b8661a827", 223 | "version_major": 2, 224 | "version_minor": 0 225 | }, 226 | "text/plain": [ 227 | "Output(outputs=({'output_type': 'stream', 'text': \"{'version': '2.7.0', 'reference': {'id': 'hg38', 'name': 'H…" 228 | ] 229 | }, 230 | "metadata": {}, 231 | "output_type": "display_data" 232 | } 233 | ], 234 | "source": [ 235 | "browser.out" 236 | ] 237 | }, 238 | { 239 | "cell_type": "markdown", 240 | "metadata": {}, 241 | "source": [ 242 | "## Charging local files\n", 243 | "NB: `igv.js` tries to load a file `undefined.fai` which causes an error. Maybe due to the use of `localhost:8000` -- activate it with `python -m http.server` in your files directory." 244 | ] 245 | }, 246 | { 247 | "cell_type": "code", 248 | "execution_count": 16, 249 | "metadata": {}, 250 | "outputs": [], 251 | "source": [ 252 | "genome2 = {\n", 253 | " 'name': 'Example chr6p',\n", 254 | " 'fastaURL': 'http://localhost:8000/chr6p.fa',\n", 255 | " 'indexURL': 'http://localhost:8000/chr6p.fa.fai',\n", 256 | "}" 257 | ] 258 | }, 259 | { 260 | "cell_type": "code", 261 | "execution_count": 17, 262 | "metadata": {}, 263 | "outputs": [], 264 | "source": [ 265 | "pgf6p_on_chr6p_track = {\n", 266 | " 'name': 'PGF 6p on chr6p',\n", 267 | " 'format': 'refgene',\n", 268 | " 'url': 'http://localhost:8000/PGF_6p_on_chr6p.bam',\n", 269 | " 'indexURL': 'http://localhost:8000/PGF_6p_on_chr6p.bai',\n", 270 | "}" 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": 18, 276 | "metadata": {}, 277 | "outputs": [], 278 | "source": [ 279 | "browser2 = igv.IgvBrowser(genome=ReferenceGenome(**genome2))" 280 | ] 281 | }, 282 | { 283 | "cell_type": "code", 284 | "execution_count": 19, 285 | "metadata": {}, 286 | "outputs": [ 287 | { 288 | "data": { 289 | "application/vnd.jupyter.widget-view+json": { 290 | "model_id": "724dc1200f87444ba368df558e92e530", 291 | "version_major": 2, 292 | "version_minor": 0 293 | }, 294 | "text/plain": [ 295 | "IgvBrowser(genome=ReferenceGenome(fastaURL='http://localhost:8000/chr6p.fa', indexURL='http://localhost:8000/c…" 296 | ] 297 | }, 298 | "metadata": {}, 299 | "output_type": "display_data" 300 | } 301 | ], 302 | "source": [ 303 | "browser2" 304 | ] 305 | }, 306 | { 307 | "cell_type": "code", 308 | "execution_count": 20, 309 | "metadata": {}, 310 | "outputs": [], 311 | "source": [ 312 | "import urllib.request" 313 | ] 314 | }, 315 | { 316 | "cell_type": "code", 317 | "execution_count": 21, 318 | "metadata": {}, 319 | "outputs": [ 320 | { 321 | "ename": "URLError", 322 | "evalue": "", 323 | "output_type": "error", 324 | "traceback": [ 325 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 326 | "\u001b[0;31mConnectionRefusedError\u001b[0m Traceback (most recent call last)", 327 | "\u001b[0;32m~/mambaforge/lib/python3.8/urllib/request.py\u001b[0m in \u001b[0;36mdo_open\u001b[0;34m(self, http_class, req, **http_conn_args)\u001b[0m\n\u001b[1;32m 1349\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1350\u001b[0;31m h.request(req.get_method(), req.selector, req.data, headers,\n\u001b[0m\u001b[1;32m 1351\u001b[0m encode_chunked=req.has_header('Transfer-encoding'))\n", 328 | "\u001b[0;32m~/mambaforge/lib/python3.8/http/client.py\u001b[0m in \u001b[0;36mrequest\u001b[0;34m(self, method, url, body, headers, encode_chunked)\u001b[0m\n\u001b[1;32m 1254\u001b[0m \u001b[0;34m\"\"\"Send a complete request to the server.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1255\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_send_request\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmethod\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbody\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mheaders\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mencode_chunked\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1256\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 329 | "\u001b[0;32m~/mambaforge/lib/python3.8/http/client.py\u001b[0m in \u001b[0;36m_send_request\u001b[0;34m(self, method, url, body, headers, encode_chunked)\u001b[0m\n\u001b[1;32m 1300\u001b[0m \u001b[0mbody\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_encode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbody\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'body'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1301\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mendheaders\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbody\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mencode_chunked\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mencode_chunked\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1302\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 330 | "\u001b[0;32m~/mambaforge/lib/python3.8/http/client.py\u001b[0m in \u001b[0;36mendheaders\u001b[0;34m(self, message_body, encode_chunked)\u001b[0m\n\u001b[1;32m 1249\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mCannotSendHeader\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1250\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_send_output\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmessage_body\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mencode_chunked\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mencode_chunked\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1251\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 331 | "\u001b[0;32m~/mambaforge/lib/python3.8/http/client.py\u001b[0m in \u001b[0;36m_send_output\u001b[0;34m(self, message_body, encode_chunked)\u001b[0m\n\u001b[1;32m 1009\u001b[0m \u001b[0;32mdel\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_buffer\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1010\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmsg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1011\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 332 | "\u001b[0;32m~/mambaforge/lib/python3.8/http/client.py\u001b[0m in \u001b[0;36msend\u001b[0;34m(self, data)\u001b[0m\n\u001b[1;32m 949\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mauto_open\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 950\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconnect\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 951\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 333 | "\u001b[0;32m~/mambaforge/lib/python3.8/http/client.py\u001b[0m in \u001b[0;36mconnect\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 920\u001b[0m \u001b[0;34m\"\"\"Connect to the host and port specified in __init__.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 921\u001b[0;31m self.sock = self._create_connection(\n\u001b[0m\u001b[1;32m 922\u001b[0m (self.host,self.port), self.timeout, self.source_address)\n", 334 | "\u001b[0;32m~/mambaforge/lib/python3.8/socket.py\u001b[0m in \u001b[0;36mcreate_connection\u001b[0;34m(address, timeout, source_address)\u001b[0m\n\u001b[1;32m 807\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 808\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 809\u001b[0m \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 335 | "\u001b[0;32m~/mambaforge/lib/python3.8/socket.py\u001b[0m in \u001b[0;36mcreate_connection\u001b[0;34m(address, timeout, source_address)\u001b[0m\n\u001b[1;32m 795\u001b[0m \u001b[0msock\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbind\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msource_address\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 796\u001b[0;31m \u001b[0msock\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconnect\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msa\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 797\u001b[0m \u001b[0;31m# Break explicitly a reference cycle\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 336 | "\u001b[0;31mConnectionRefusedError\u001b[0m: [Errno 111] Connection refused", 337 | "\nDuring handling of the above exception, another exception occurred:\n", 338 | "\u001b[0;31mURLError\u001b[0m Traceback (most recent call last)", 339 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0murl\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0murllib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrequest\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0murlopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'http://localhost:8000/chr6p.fa.fai'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 340 | "\u001b[0;32m~/mambaforge/lib/python3.8/urllib/request.py\u001b[0m in \u001b[0;36murlopen\u001b[0;34m(url, data, timeout, cafile, capath, cadefault, context)\u001b[0m\n\u001b[1;32m 220\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 221\u001b[0m \u001b[0mopener\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_opener\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 222\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mopener\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 223\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 224\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0minstall_opener\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mopener\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 341 | "\u001b[0;32m~/mambaforge/lib/python3.8/urllib/request.py\u001b[0m in \u001b[0;36mopen\u001b[0;34m(self, fullurl, data, timeout)\u001b[0m\n\u001b[1;32m 523\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 524\u001b[0m \u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maudit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'urllib.Request'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfull_url\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mheaders\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_method\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 525\u001b[0;31m \u001b[0mresponse\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_open\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mreq\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 526\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 527\u001b[0m \u001b[0;31m# post-process response\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 342 | "\u001b[0;32m~/mambaforge/lib/python3.8/urllib/request.py\u001b[0m in \u001b[0;36m_open\u001b[0;34m(self, req, data)\u001b[0m\n\u001b[1;32m 540\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 541\u001b[0m \u001b[0mprotocol\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mreq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtype\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 542\u001b[0;31m result = self._call_chain(self.handle_open, protocol, protocol +\n\u001b[0m\u001b[1;32m 543\u001b[0m '_open', req)\n\u001b[1;32m 544\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 343 | "\u001b[0;32m~/mambaforge/lib/python3.8/urllib/request.py\u001b[0m in \u001b[0;36m_call_chain\u001b[0;34m(self, chain, kind, meth_name, *args)\u001b[0m\n\u001b[1;32m 500\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mhandler\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mhandlers\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 501\u001b[0m \u001b[0mfunc\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgetattr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhandler\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmeth_name\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 502\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 503\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 504\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 344 | "\u001b[0;32m~/mambaforge/lib/python3.8/urllib/request.py\u001b[0m in \u001b[0;36mhttp_open\u001b[0;34m(self, req)\u001b[0m\n\u001b[1;32m 1377\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1378\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mhttp_open\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreq\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1379\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdo_open\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhttp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclient\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mHTTPConnection\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreq\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1380\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1381\u001b[0m \u001b[0mhttp_request\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mAbstractHTTPHandler\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdo_request_\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 345 | "\u001b[0;32m~/mambaforge/lib/python3.8/urllib/request.py\u001b[0m in \u001b[0;36mdo_open\u001b[0;34m(self, http_class, req, **http_conn_args)\u001b[0m\n\u001b[1;32m 1351\u001b[0m encode_chunked=req.has_header('Transfer-encoding'))\n\u001b[1;32m 1352\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mOSError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# timeout error\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1353\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mURLError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1354\u001b[0m \u001b[0mr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mh\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgetresponse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1355\u001b[0m \u001b[0;32mexcept\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 346 | "\u001b[0;31mURLError\u001b[0m: " 347 | ] 348 | } 349 | ], 350 | "source": [ 351 | "url = urllib.request.urlopen('http://localhost:8000/chr6p.fa.fai')" 352 | ] 353 | }, 354 | { 355 | "cell_type": "code", 356 | "execution_count": null, 357 | "metadata": {}, 358 | "outputs": [], 359 | "source": [ 360 | "print(url.read(100).decode('utf-8'))" 361 | ] 362 | }, 363 | { 364 | "cell_type": "code", 365 | "execution_count": null, 366 | "metadata": {}, 367 | "outputs": [], 368 | "source": [] 369 | } 370 | ], 371 | "metadata": { 372 | "kernelspec": { 373 | "display_name": "Python 3", 374 | "language": "python", 375 | "name": "python3" 376 | }, 377 | "language_info": { 378 | "codemirror_mode": { 379 | "name": "ipython", 380 | "version": 3 381 | }, 382 | "file_extension": ".py", 383 | "mimetype": "text/x-python", 384 | "name": "python", 385 | "nbconvert_exporter": "python", 386 | "pygments_lexer": "ipython3", 387 | "version": "3.8.6" 388 | } 389 | }, 390 | "nbformat": 4, 391 | "nbformat_minor": 4 392 | } 393 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["jupyter_packaging~=0.7.0", "jupyterlab>=3.0.0,==3.*", "setuptools>=40.8.0", "wheel"] 3 | build-backend = "setuptools.build_meta" 4 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal=1 3 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from setuptools import setup, find_packages 3 | import os 4 | from os.path import join as pjoin 5 | from distutils import log 6 | 7 | from jupyter_packaging import ( 8 | create_cmdclass, 9 | install_npm, 10 | ensure_targets, 11 | combine_commands, 12 | get_version, 13 | ) 14 | 15 | # 16 | here = os.path.dirname(os.path.abspath(__file__)) 17 | 18 | log.set_verbosity(log.DEBUG) 19 | log.info('setup.py entered') 20 | log.info('$PATH=%s' % os.environ['PATH']) 21 | 22 | name = 'ipyigv' 23 | LONG_DESCRIPTION = 'A Jupyter wrapper for the igv.js library' 24 | 25 | # Get ipyigv version 26 | version = get_version(pjoin(name, '_version.py')) 27 | 28 | js_dir = pjoin(here, 'js') 29 | 30 | # Representative files that should exist after a successful build 31 | jstargets = [ 32 | pjoin(js_dir, 'dist', 'index.js'), 33 | ] 34 | 35 | data_files_spec = [ 36 | ('share/jupyter/nbextensions/jupyter-igv', 'ipyigv/nbextension', '*.*'), 37 | ('share/jupyter/labextensions/jupyter-igv', 'ipyigv/labextension', '**'), 38 | ('etc/jupyter/nbconfig/notebook.d', '.', 'jupyter-igv.json'), 39 | ] 40 | 41 | cmdclass = create_cmdclass('jsdeps', data_files_spec=data_files_spec) 42 | cmdclass['jsdeps'] = combine_commands( 43 | install_npm(js_dir, build_cmd='build'), 44 | ensure_targets(jstargets), 45 | ) 46 | 47 | setup_args = dict( 48 | name=name, 49 | version=version, 50 | description='A Jupyter wrapper for the igv.js library', 51 | long_description=LONG_DESCRIPTION, 52 | include_package_data=True, 53 | install_requires=[ 54 | 'ipywidgets>=7.6.0,<8' 55 | ], 56 | extras_require={ 57 | "test": ["pytest>4.6"] 58 | }, 59 | packages=find_packages(), 60 | zip_safe=False, 61 | cmdclass=cmdclass, 62 | author='Project Jupyter', 63 | author_email='jeandavid.harrouet@hopsys.com', 64 | url='https://github.com/QuantStack/ipyigv', 65 | keywords=[ 66 | 'ipython', 67 | 'jupyter', 68 | 'widgets', 69 | ], 70 | package_data={'ipyigv': ['public_genomes.json']}, 71 | classifiers=[ 72 | 'Development Status :: 4 - Beta', 73 | 'Framework :: IPython', 74 | 'Intended Audience :: Developers', 75 | 'Intended Audience :: Science/Research', 76 | 'Topic :: Multimedia :: Graphics', 77 | 'Programming Language :: Python :: 2', 78 | 'Programming Language :: Python :: 2.7', 79 | 'Programming Language :: Python :: 3', 80 | 'Programming Language :: Python :: 3.3', 81 | 'Programming Language :: Python :: 3.4', 82 | 'Programming Language :: Python :: 3.5', 83 | 'Programming Language :: Python :: 3.6', 84 | 'Programming Language :: Python :: 3.7', 85 | ], 86 | ) 87 | 88 | setup(**setup_args) 89 | --------------------------------------------------------------------------------