Skip to content

[WIP] Update #28

New issue

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

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

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions example_browser/browser_tracks.ini
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,37 @@ title = Kc DpnII (Li et al. 2015)
colormap = RdYlBu_r
depth = 200000
transform = log1p
x labels = yes
boundaries_file = domains.bed

[boundaries]
file = domains.bed
file_type = domains
overlay_previous = share-y
color = None

[spacer]
width = 0.05
height = 0.05

[tad state]
file = tad_classification.bed
width = 0.5
height = 0.5
title = TAD state
display = collapsed
labels = off
labels = false

[tad-separation score]
file = tad_score.gz
width = 10
height = 10
type = lines
title= TAD separation score (Ramirez et al.)
file_type = bedgraph_matrix

[genes]
file = dm3_genes.bed.gz
width = 20
height = 20
title = genes
fontsize = 12
global max row = yes
global_max_row = true
labels = true

[vlines]
file = domains.bed
Expand Down
2 changes: 1 addition & 1 deletion hicbrowser/client/js/templates.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion hicbrowser/client/templates/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="row">
<div class="col-md-6">
<p>HiCBrowser is a simple web browser to visualize <strong>Hi-C</strong> and other genomic tracks.
<p>It is based on <strong>HiCExplorer</strong>, a set of programs that enable you to process, normalize, analyze and visualize Hi-C data.</p>
<p>It is based on <strong>pyGenomeTracks</strong>, a program and library to plot beautiful genome browser tracks.</p>
</div>
<div class="col-md-6">
<!-- build:src /static/img/vis.png -->
Expand Down
2 changes: 1 addition & 1 deletion hicbrowser/runBrowser.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def parse_arguments(args=None):

parser.add_argument('--htmlFolder',
help='File where the template index.html file is located. The default is'
'fine unless the contents wants to be personalized. The full path '
' fine unless the contents wants to be personalized. The full path '
'has to be given.',
default=None)

Expand Down
2 changes: 1 addition & 1 deletion hicbrowser/static/js/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ this["Templates"]["gene"] = Handlebars.template({"1":function(container,depth0,h
},"useData":true});

this["Templates"]["index"] = Handlebars.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
return "<hr>\n<div class=\"row\">\n <div class=\"col-md-6\">\n <p>HiCBrowser is a simple web browser to visualize <strong>Hi-C</strong> and other genomic tracks. \n <p>It is based on <strong>HiCExplorer</strong>, a set of programs that enable you to process, normalize, analyze and visualize Hi-C data.</p>\n </div>\n <div class=\"col-md-6\">\n <!-- build:src /static/img/vis.png -->\n <img class=\"img-responsive\" src=\"../static/img/vis.png\" alt=\"\">\n <!-- /build -->\n </div>\n</div>\n<br>\n<br>\n";
return "<hr>\n<div class=\"row\">\n <div class=\"col-md-6\">\n <p>HiCBrowser is a simple web browser to visualize <strong>Hi-C</strong> and other genomic tracks. \n <p>It is based on <strong>pyGenomeTracks</strong>, a program and library to plot beautiful genome browser tracks.</p>\n </div>\n <div class=\"col-md-6\">\n <!-- build:src /static/img/vis.png -->\n <img class=\"img-responsive\" src=\"../static/img/vis.png\" alt=\"\">\n <!-- /build -->\n </div>\n</div>\n<br>\n<br>\n";
},"useData":true});

this["Templates"]["loading"] = Handlebars.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
Expand Down
2 changes: 1 addition & 1 deletion hicbrowser/static/js/App.min.js

Large diffs are not rendered by default.

21 changes: 11 additions & 10 deletions hicbrowser/tracks2json.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
from collections import OrderedDict

from bx.intervals.intersection import IntervalTree, Interval
import hicexplorer.readBed
from hicexplorer.trackPlot import file_to_intervaltree, opener, change_chrom_names
import pygenometracks.readBed
from pygenometracks.tracks.GenomeTrack import GenomeTrack
from pygenometracks.utilities import file_to_intervaltree, opener


DEFAULT_TRACK_HEIGHT = 3 # in centimeters
Expand Down Expand Up @@ -44,7 +45,7 @@ def __init__(self, tracks_file, fig_width=DEFAULT_FIGURE_WIDTH, fig_height=None)
# initialize each track
self.track_obj_list = []
for idx, properties in enumerate(self.track_list):
print properties
print(properties)
if 'spacer' in properties:
self.track_obj_list.append(PlotSpacer(properties))
continue
Expand Down Expand Up @@ -139,7 +140,7 @@ def set_interval_values_vlines(self, chrom_region, start_region, end_region):
vlines_list = []

if chrom_region not in self.vlines_intval_tree.keys():
chrom_region = change_chrom_names(chrom_region)
chrom_region = GenomeTrack.change_chrom_names(chrom_region)
for region in self.vlines_intval_tree[chrom_region].find(start_region - 10000,
end_region + 10000):
vlines_list.append(region.start)
Expand All @@ -153,9 +154,9 @@ def parse_tracks(self, tracks_file):
:param tracks_file: file path containing the track configuration
:return: array of dictionaries and vlines_file. One dictionary per track
"""
from ConfigParser import SafeConfigParser
from configparser import ConfigParser
from ast import literal_eval
parser = SafeConfigParser(None, MultiDict)
parser = ConfigParser(None, MultiDict)
parser.readfp(open(tracks_file, 'r'))

track_list = []
Expand Down Expand Up @@ -296,7 +297,7 @@ def set_interval_values(self, chrom_region, start_region, end_region):
self.properties['file']))

if chrom_region not in self.bw.chroms().keys():
chrom_region = change_chrom_names(chrom_region)
chrom_region = GenomeTrack.change_chrom_names(chrom_region)

if chrom_region not in self.bw.chroms().keys():
sys.exit("Can not read region {} from bigwig file:\n\n"
Expand Down Expand Up @@ -469,7 +470,7 @@ def process_bed(self, region_start, region_end):
bp_per_inch = region_len / self.fig_width
font_in_bp = font_in_inches * bp_per_inch
self.len_w = font_in_bp
print "len of w set to: {} bp".format(self.len_w)
print("len of w set to: {} bp".format(self.len_w))
else:
self.len_w = 1

Expand Down Expand Up @@ -542,7 +543,7 @@ def process_bed(self, region_start, region_end):
if free_row > self.max_num_row[bed.chromosome]:
self.max_num_row[bed.chromosome] = free_row

print self.max_num_row
print(self.max_num_row)

if valid_intervals == 0:
sys.stderr.write("No valid intervals were found in file {}".format(self.properties['file_name']))
Expand All @@ -552,7 +553,7 @@ def set_interval_values(self, chrom_region, start_region, end_region):
self.process_bed(start_region, end_region)

if chrom_region not in self.interval_tree.keys():
chrom_region = change_chrom_names(chrom_region)
chrom_region = GenomeTrack.change_chrom_names(chrom_region)

genes_overlap = self.interval_tree[chrom_region].find(start_region, end_region)

Expand Down
103 changes: 38 additions & 65 deletions hicbrowser/views.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
import sys
import numpy as np
from flask import Flask, render_template, request, send_file
from flask import Flask, render_template, request, send_file, Blueprint

import os
from os.path import exists

import json

import hicexplorer.trackPlot
import hicbrowser.utilities
import pygenometracks.plotTracks
from pygenometracks.tracks.GenomeTrack import GenomeTrack
import pygenometracks.tracksClass as pgttc
from pygenometracks.utilities import file_to_intervaltree, opener, to_string
import hicbrowser.tracks2json


from ConfigParser import SafeConfigParser
from configparser import ConfigParser

hicexplorer.trackPlot.DEFAULT_WIDTH_RATIOS = (0.89, 0.11)
hicexplorer.trackPlot.DEFAULT_MARGINS = {'left': 0.02, 'right': 0.98, 'bottom': 0, 'top': 1}
pgttc.DEFAULT_WIDTH_RATIOS = (0.01, 0.89, 0.11)
pgttc.DEFAULT_MARGINS = {'left': 0.02, 'right': 0.98, 'bottom': 0, 'top': 1}

def default(o):
"""
Transform np.integers to integers as np.integers are
not compatible with json dump
"""
if isinstance(o, np.integer):
return int(o)
else:
return o

def get_TAD_for_gene(gene_name):
"""
Expand All @@ -29,48 +40,14 @@ def get_TAD_for_gene(gene_name):
if gene_name in gene2pos:
# get gene position
chrom_, start_, end_ = gene2pos[gene_name]
if chrom_ not in tads_intval_tree.keys():
if chrom_.startswith('chr'):
chrom_ = chrom_[3:]
else:
chrom_ = 'chr' + chrom_
tad_pos = sorted( tads_intval_tree[chrom_].search(start_, end_) )[0]
if chrom_ not in tads_intval_tree:
chrom_ = GenomeTrack.change_chrom_names(chrom_)
tad_pos = sorted(tads_intval_tree[chrom_][start_:end_])[0]
return chrom_, tad_pos.begin, tad_pos.end
else:
return None


def get_region(region_string):
"""
splits a region string into
a chrom, start_region, end_region tuple
The region_string format is chr:start-end
"""
if region_string:
# separate the chromosome name and the location using the ':' character
chrom, position = region_string.strip().split(":")

# clean up the position
for char in ",.;|!{}()":
position = position.replace(char, '')
position_list = position.split("-")
try:
region_start = int(position_list[0])
except IndexError:
region_start = 0
try:
region_end = int(position_list[1])
except IndexError:
region_end = 1e15 # a huge number
if region_start < 0:
region_start = 0
if region_end <= region_start:
exit("Please check that the region end is larger than the region start.\n"
"Values given:\nstart: {}\nend: {}\n".format(region_start, region_end))

return chrom, region_start, region_end


def snap_to_resolution(start, end):
"""
given a start and end, guesses the resolution and
Expand Down Expand Up @@ -115,10 +92,10 @@ def check_static_img_folders():
try:
os.makedirs(dir_path + '/images')
except:
sys.exit("Images folder does not exists and can not be created.\n"
"Check that the user has permission to create the folder under\n"
"the current directory. The path for the folder is:\n"
"{}".format(dir_path + '/images/'))
raise Exception("Images folder does not exists and can not be created.\n"
"Check that the user has permission to create the folder under\n"
"the current directory. The path for the folder is:\n"
"{}".format(dir_path + '/images/'))

if not os.path.isdir(dir_path + '/images/genes'):
os.makedirs(dir_path + '/images/genes')
Expand All @@ -132,7 +109,7 @@ def check_static_img_folders():

def main(config_file, port, numProc, template_folder=None, debug=False):

config = SafeConfigParser()
config = ConfigParser()
config.readfp(open(config_file, 'r'))

kwargs = {}
Expand All @@ -142,7 +119,6 @@ def main(config_file, port, numProc, template_folder=None, debug=False):

app = Flask(__name__, **kwargs)

from flask import Blueprint
img_path = check_static_img_folders()

# register an static path for images using Blueprint
Expand All @@ -154,19 +130,16 @@ def main(config_file, port, numProc, template_folder=None, debug=False):
# setup up the tracks. It works as follows
# the config.ini file is read and split into individual tracks
# that are saved on a temporary file.
# then, hicexplorer.trackPlot object is initialized with this track and
# then, pygenometracks.tracksClass.PlotTracks object is initialized with this track and
# store on a list (trp_list). If the tracks were not to be splited in
# individual files, trackPlot will plot everything togeher. By splitting
# individual files, plotTracks will plot everything togeher. By splitting
# them we take advantage of multiprocessing to generate each image on
# a different core. Naturally, if using only one core then nothing is gained.
track_file = config.get("browser", "tracks")
trp_list = []
for track in track_file.split(" "):
track_list = hicbrowser.utilities.parse_tracks(track)
for temp_file_name, section_name in track_list:
print "\n{}".format(section_name)
trp_list.append(hicexplorer.trackPlot.PlotTracks(temp_file_name, fig_width=40, dpi=70))
os.unlink(temp_file_name)
trp_list.append(pgttc.PlotTracks(track))


tad_img_root = img_path + '/genes'
img_root = img_path + '/browser'
Expand All @@ -176,7 +149,7 @@ def main(config_file, port, numProc, template_folder=None, debug=False):

tads_file = config.get('general', 'TAD intervals')
global tads_intval_tree
tads_intval_tree, __, __ = hicexplorer.trackPlot.file_to_intervaltree(tads_file)
tads_intval_tree, __, __ = file_to_intervaltree(tads_file)

# initialize gene name to position mapping
genes = config.get('general', 'genes')
Expand All @@ -188,9 +161,9 @@ def main(config_file, port, numProc, template_folder=None, debug=False):
track_file = config.get('general', 'tracks')
tads = hicbrowser.tracks2json.SetTracks(track_file, fig_width=40)

from hicexplorer.trackPlot import opener
with opener(genes) as fh:
for line in fh.readlines():
line = to_string(line)
if line.startswith('browser') or line.startswith('track') or line.startswith('#'):
continue
gene_chrom, gene_start, gene_end, gene_name = line.strip().split("\t")[0:4]
Expand All @@ -201,7 +174,7 @@ def main(config_file, port, numProc, template_folder=None, debug=False):
sys.stderr.write("Problem with line {}".format(line))
pass
gene2pos[gene_name.lower()] = (gene_chrom, gene_start, gene_end)

@app.route('/', methods=['GET'])
def index():
return render_template("index.html")
Expand Down Expand Up @@ -238,7 +211,6 @@ def get_tad(gene_name):

data['tracks'] = d
res = json.dumps(data)

return res

@app.route('/browser/<query>', methods=['GET'])
Expand All @@ -248,10 +220,11 @@ def browser(query):
# check if the query is a valid gene name
if gene_name in gene2pos:
chromosome, start, end = gene2pos[gene_name]
start -= 50000
start -= 50000 if start > 50000 else 0
end += 50000
else:
chromosome, start, end = get_region(query.strip())
chromosome, start, end = pygenometracks.plotTracks.get_region(query.strip())
print("chr:{}".format(chromosome))
if end - start < 10000:
sys.stderr.write("region to small ({}bp), enlarging it.".format(end - start))
start -= 5000
Expand Down Expand Up @@ -340,7 +313,7 @@ def browser(query):
'content': content,
'start': start,
'end': end}
json_data = json.dumps(data)
json_data = json.dumps(data, default=default)

return json_data

Expand All @@ -355,7 +328,7 @@ def get_image():
return None
if query:
query = query.strip()
chromosome, start, end = get_region(query)
chromosome, start, end = pygenometracks.plotTracks.get_region(query)

outfile = "{}/{}_{}_{}_{}.png".format(img_root,
chromosome,
Expand All @@ -364,7 +337,7 @@ def get_image():
img_id)
# if the figure does no exists, then
# hicexplorer.trackPlot is called (trp_list[img_id] contains
# an instance of hicexplorer.trackPlot
# an instance of pygenometracks.tracksClass.PlotTracks)
if not exists(outfile):
trp_list[img_id].plot(outfile, chromosome, start, end)

Expand Down
Loading