diff options
author | zsloan | 2018-10-24 17:23:18 +0000 |
---|---|---|
committer | zsloan | 2018-10-24 17:23:18 +0000 |
commit | 9cfb01cab4bcf6bf87ff8f7bfcf603ed349fbd87 (patch) | |
tree | dcd87068f45f441bfc9e96efbd1f042015a98aec | |
parent | 7d1a681029e4efb73b4a0f07ac37c15764b15eb8 (diff) | |
download | genenetwork2-9cfb01cab4bcf6bf87ff8f7bfcf603ed349fbd87.tar.gz |
- SNP Browser is mostly complete; just need to test more and add SNP density chart if results exceed some number (5000 on GN1)
- Removed unnecessary options from the mode bar for the trait page Plotly figures and changed the default to highlight points the mouse is hovering over
- Changed some file/function names related to mapping, which previously were erroneously named "marker_regression"
14 files changed, 497 insertions, 121 deletions
diff --git a/wqflask/base/webqtlConfig.py b/wqflask/base/webqtlConfig.py index 4708bf0a..c9052c83 100644 --- a/wqflask/base/webqtlConfig.py +++ b/wqflask/base/webqtlConfig.py @@ -34,6 +34,10 @@ PUBMEDLINK_URL = "http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db= UCSC_BLAT = 'http://genome.ucsc.edu/cgi-bin/hgBlat?org=%s&db=%s&type=0&sort=0&output=0&userSeq=%s' UTHSC_BLAT = 'http://ucscbrowser.genenetwork.org/cgi-bin/hgBlat?org=%s&db=%s&type=0&sort=0&output=0&userSeq=%s' UTHSC_BLAT2 = 'http://ucscbrowserbeta.genenetwork.org/cgi-bin/hgBlat?org=%s&db=%s&type=0&sort=0&output=0&userSeq=%s' +GENOMEBROWSER_URL="https://genome.ucsc.edu/cgi-bin/hgTracks?db=%s&position=%s" +NCBI_LOCUSID = "http://www.ncbi.nlm.nih.gov/gene?cmd=Retrieve&dopt=Graphics&list_uids=%s" +ENSEMBLETRANSCRIPT_URL="http://useast.ensembl.org/Mus_musculus/Transcript/Idhistory?t=%s" +DBSNP = 'http://www.ncbi.nlm.nih.gov/SNP/snp_ref.cgi?type=rs&rs=%s' # Temporary storage (note that this TMPDIR can be set as an # environment variable - use utility.tools.TEMPDIR when you diff --git a/wqflask/wqflask/marker_regression/marker_regression_gn1.py b/wqflask/wqflask/marker_regression/display_mapping_results.py index 21dd897a..09646f57 100644 --- a/wqflask/wqflask/marker_regression/marker_regression_gn1.py +++ b/wqflask/wqflask/marker_regression/display_mapping_results.py @@ -51,7 +51,7 @@ logger = utility.logger.getLogger(__name__ ) ######################################### # Inteval Mapping Plot Page ######################################### -class MarkerRegression(object): +class DisplayMappingResults(object): cMGraphInterval = 5 GRAPH_MIN_WIDTH = 900 GRAPH_MAX_WIDTH = 10000 # Don't set this too high diff --git a/wqflask/wqflask/marker_regression/marker_regression.py b/wqflask/wqflask/marker_regression/run_mapping.py index 17089c13..b604b467 100644 --- a/wqflask/wqflask/marker_regression/marker_regression.py +++ b/wqflask/wqflask/marker_regression/run_mapping.py @@ -45,7 +45,7 @@ from base.webqtlConfig import TMPDIR, GENERATED_TEXT_DIR import utility.logger logger = utility.logger.getLogger(__name__ ) -class MarkerRegression(object): +class RunMapping(object): def __init__(self, start_vars, temp_uuid): diff --git a/wqflask/wqflask/snp_browser/snp_browser.py b/wqflask/wqflask/snp_browser/snp_browser.py index df68d4a0..393b8507 100644 --- a/wqflask/wqflask/snp_browser/snp_browser.py +++ b/wqflask/wqflask/snp_browser/snp_browser.py @@ -8,21 +8,27 @@ from utility.logger import getLogger logger = getLogger(__name__ ) from base import species +from base import webqtlConfig class SnpBrowser(object): MAXSNPRETURN = 5000 def __init__(self, start_vars): - self.strain_list = get_browser_sample_list() + self.strain_lists = get_browser_sample_lists() self.initialize_parameters(start_vars) if self.first_run == "false": if self.limit_strains == "true": self.header_fields = get_header_list(self.variant_type, self.chosen_strains) else: - self.header_fields = get_header_list(self.variant_type, self.strain_list) - self.filtered_results = self.get_table_results() + self.header_fields = get_header_list(self.variant_type, self.strain_lists, self.species_name) + self.filtered_results = self.get_browser_results() + + if len(self.filtered_results) <= 5000: + self.table_rows = self.get_table_rows() + else: + self.table_rows = [] def initialize_parameters(self, start_vars): self.first_run = "true" @@ -39,7 +45,7 @@ class SnpBrowser(object): self.species_id = 0 #Using this to indicate "All Species" #ZS: Currently this is just assuming mouse for determining the chromosomes. - # This logic may have to change depending upon what other species are added or how we want to deal with an "All Species" option + # This logic may have to change depending upon what other species are added self.chr_list = [] species_ob = species.TheSpecies(species_name="Mouse") for key in species_ob.chromosomes.chromosomes: @@ -61,7 +67,14 @@ class SnpBrowser(object): self.limit_strains = "true" else: self.limit_strains = "false" - self.chosen_strains = start_vars['chosen_strains'].split(",") + self.chosen_strains_mouse = start_vars['chosen_strains_mouse'].split(",") + self.chosen_strains_rat = start_vars['chosen_strains_rat'].split(",") + + if self.species_id == 1: + self.chosen_strains = self.chosen_strains_mouse + elif self.species_id == 2: + self.chosen_strains = self.chosen_strains_rat + self.domain = start_vars['domain'] self.function = start_vars['function'] self.source = start_vars['source'] @@ -89,15 +102,19 @@ class SnpBrowser(object): self.limit_strains = "true" - self.chosen_strains = ["C57BL/6J", - "DBA/2J", - "A/J", - "129S1/SvImJ", - "NOD/ShiLtJ", - "NZO/HlLtJ", - "WSB/EiJ", - "PWK/PhJ", - "CAST/EiJ"] + self.chosen_strains_mouse = ["C57BL/6J", + "DBA/2J", + "A/J", + "129S1/SvImJ", + "NOD/ShiLtJ", + "NZO/HlLtJ", + "WSB/EiJ", + "PWK/PhJ", + "CAST/EiJ"] + self.chosen_strains_rat = ["F344"] + self.chosen_strains_all = self.chosen_strains_mouse + self.chosen_strains_rat + + self.chosen_strains = self.chosen_strains_mouse self.domain = "All" self.function = "All" @@ -108,11 +125,14 @@ class SnpBrowser(object): self.redundant = "false" self.diff_alleles = "true" - def get_table_results(self): + def get_browser_results(self): self.snp_list = None if self.gene_name != "": - query = "SELECT geneSymbol, chromosome, txStart, txEnd FROM GeneList WHERE SpeciesId = %s AND geneSymbol = %s" % (self.species_id, self.gene_name) + if self.species_id != 0: + query = "SELECT geneSymbol, chromosome, txStart, txEnd FROM GeneList WHERE SpeciesId = %s AND geneSymbol = '%s'" % (self.species_id, self.gene_name) + else: + query = "SELECT geneSymbol, chromosome, txStart, txEnd FROM GeneList WHERE geneSymbol = '%s'" % (self.gene_name) result = g.db.execute(query).fetchone() if result: self.gene_name, self.chr, self.start_mb, self.end_mb = result @@ -120,9 +140,12 @@ class SnpBrowser(object): result_snp = None if self.variant_type == "SNP": if self.gene_name[:2] == "rs": - query = "SELECT Id, Chromosome, Position, Position+0.000001 FROM SnpAll WHERE Rs = %s" % self.gene_name + query = "SELECT Id, Chromosome, Position, Position+0.000001 FROM SnpAll WHERE Rs = '%s'" % self.gene_name else: - query = "SELECT Id, Chromosome, Position, Position+0.000001 ForM SnpAll where SpeciesId = %s AND SnpName = %s" % (self.species_id, self.gene_name) + if self.species_id != 0: + query = "SELECT Id, Chromosome, Position, Position+0.000001 ForM SnpAll where SpeciesId = %s AND SnpName = '%s'" % (self.species_id, self.gene_name) + else: + query = "SELECT Id, Chromosome, Position, Position+0.000001 ForM SnpAll where SnpName = '%s'" % (self.gene_name) result_snp = g.db.execute(query).fetchall() if result_snp: self.snp_list = [item[0] for item in result_snp] @@ -133,7 +156,10 @@ class SnpBrowser(object): return elif self.variant_type == "InDel": if self.gene_name[0] == "I": - query = "SELECT Id, Chromosome, Mb_start, Mb_end FROM IndelAll WHERE SpeciesId = %s AND Name = %s" % (self.species_id, self.gene_name) + if self.species_id != 0: + query = "SELECT Id, Chromosome, Mb_start, Mb_end FROM IndelAll WHERE SpeciesId = %s AND Name = '%s'" % (self.species_id, self.gene_name) + else: + query = "SELECT Id, Chromosome, Mb_start, Mb_end FROM IndelAll WHERE Name = '%s'" % (self.gene_name) result_snp = g.db.execute(query).fetchall() if result_snp: self.snp_list = [item[0] for item in result_snp] @@ -144,29 +170,59 @@ class SnpBrowser(object): return if self.variant_type == "SNP": - query = """ + mouse_query = """ SELECT - a.*, b.* + a.*, b.* FROM - SnpAll a, SnpPattern b + SnpAll a, SnpPattern b WHERE - a.SpeciesId = %s AND a.Chromosome = '%s' AND - a.Position >= %.6f AND a.Position < %.6f AND - a.Id = b.SnpId + a.SpeciesId = %s AND a.Chromosome = '%s' AND + a.Position >= %.6f AND a.Position < %.6f AND + a.Id = b.SnpId ORDER BY a.Position """ % (self.species_id, self.chr, self.start_mb, self.end_mb) - elif self.variant_type == "InDel": - query = """ + + rat_query = """ SELECT - DISTINCT a.Name, a.Chromosome, a.SourceId, a.Mb_start, a.Mb_end, a.Strand, a.Type, a.Size, a.InDelSequence, b.Name + a.*, b.* FROM - IndelAll a, SnpSource b + SnpAll a, RatSnpPattern b WHERE + a.SpeciesId = %s AND a.Chromosome = '%s' AND + a.Position >= %.6f AND a.Position < %.6f AND + a.Id = b.SnpId + ORDER BY a.Position + """ % (self.species_id, self.chr, self.start_mb, self.end_mb) + if self.species_id == 1: + query = mouse_query + elif self.species_id == 2: + query = rat_query + + elif self.variant_type == "InDel": + if species_id != 0: + query = """ + SELECT + DISTINCT a.Name, a.Chromosome, a.SourceId, a.Mb_start, a.Mb_end, a.Strand, a.Type, a.Size, a.InDelSequence, b.Name + FROM + IndelAll a, SnpSource b + WHERE a.SpeciesId = '%s' AND a.Chromosome = '%s' AND a.Mb_start >= %2.6f AND a.Mb_start < (%2.6f+.0010) AND b.Id = a.SourceId - ORDER BY a.Mb_start - """ % (self.species_id, self.chr, self.start_mb, self.end_mb) + ORDER BY a.Mb_start + """ % (self.species_id, self.chr, self.start_mb, self.end_mb) + else: + query = """ + SELECT + DISTINCT a.Name, a.Chromosome, a.SourceId, a.Mb_start, a.Mb_end, a.Strand, a.Type, a.Size, a.InDelSequence, b.Name + FROM + IndelAll a, SnpSource b + WHERE + a.Chromosome = '%s' AND + a.Mb_start >= %2.6f AND a.Mb_start < (%2.6f+.0010) AND + b.Id = a.SourceId + ORDER BY a.Mb_start + """ % (self.chr, self.start_mb, self.end_mb) results_all = g.db.execute(query).fetchall() @@ -179,7 +235,7 @@ class SnpBrowser(object): if self.limit_strains == "true" and len(self.chosen_strains) > 0: for item in self.chosen_strains: - index = self.strain_list.index(item) + index = self.strain_lists[self.species_name.lower()].index(item) strain_index_list.append(index) for seq, result in enumerate(results): @@ -189,11 +245,17 @@ class SnpBrowser(object): display_strains = [] snp_id, species_id, snp_name, rs, chr, mb, mb_2016, alleles, snp_source, conservation_score = result[:10] effect_list = result[10:26] - self.allele_list = result[27:] + if self.species_id == 1: + self.allele_list = result[27:] + elif self.species_id == 2: + self.allele_list = result[28:] if self.limit_strains == "true" and len(self.chosen_strains) > 0: for index in strain_index_list: - display_strains.append(result[27+index]) + if self.species_id == 1: + display_strains.append(result[27+index]) + elif self.species_id == 2: + display_strains.append(result[28+index]) self.allele_list = display_strains effect_info_dict = get_effect_info(effect_list) @@ -266,6 +328,150 @@ class SnpBrowser(object): return filtered_results + def get_table_rows(self): + """ Take results and put them into the order and format necessary for the tables rows """ + + if self.variant_type == "SNP": + gene_name_list = [] + for item in self.filtered_results: + if item[5] and item[5] != "": + gene_name = item[5][1] + # eliminate duplicate gene_name + if gene_name and (gene_name not in gene_name_list): + gene_name_list.append(gene_name) + if len(gene_name_list) > 0: + gene_id_name_dict = get_gene_id_name_dict(gene_name_list) + + the_rows = [] + for result in self.filtered_results: + this_row = [] + if self.variant_type == "SNP": + snp_name, rs, chr, mb, alleles, gene, transcript, exon, domain, function, function_details, snp_source, conservation_score, snp_id = result[:14] + allele_value_list = result[14:] + if rs: + snp_url = webqtlConfig.DBSNP % (rs) + snp_name = rs + else: + rs = "" + start_bp = int(mb*1000000 - 100) + end_bp = int(mb*1000000 + 100) + position_info = "chr%s:%d-%d" % (chr, start_bp, end_bp) + if self.species_id == 2: + snp_url = webqtlConfig.GENOMEBROWSER_URL % ("rn6", position_info) + else: + snp_url = webqtlConfig.GENOMEBROWSER_URL % ("mm10", position_info) + + mb = float(mb) + mb_formatted = "%2.6f" % mb + + if snp_source == "Sanger/UCLA": + source_url_1 = "http://www.sanger.ac.uk/resources/mouse/genomes/" + source_url_2 = "http://mouse.cs.ucla.edu/mousehapmap/beta/wellcome.html" + source_urls = [source_url_1, source_url_2] + else: + source_urls = [] + + if not conservation_score: + conservation_score = "" + + if gene: + gene_name = gene[1] + # if gene_name has related gene_id, use gene_id for NCBI search + if (gene_name in gene_id_name_dict) and (gene_id_name_dict[gene_name] != None and gene_id_name_dict[gene_name] != ""): + gene_id = gene_id_name_dict[gene[1]] + gene_link = webqtlConfig.NCBI_LOCUSID % gene_id + else: + gene_link = "http://www.ncbi.nln.nih.gov/entrez/query.fcgi?CMD=search&DB=gene&term=%s" % gene_name + else: + gene_name = "" + gene_link = "" + + if transcript: + transcript_link = webqtlConfig.ENSEMBLETRANSCRIPT_URL % (transcript) + else: + transcript_link = "" + + if exon: + exon = exon[1] # exon[0] is exon_id, exon[1] is exon_rank + else: + exon = "1" + + if domain: + domain_1 = domain[0] + domain_2 = domain[1] + if domain_1 == "Exon": + domain_1 = domain_1 + " " + exon + + function_list = [] + if function_details: + function_list = string.split(string.strip(function_details), ",") + function_list = map(string.strip, function_list) + function_list[0] = function_list[0].title() + function_details = ", ".join(item for item in function_list) + function_details = function_details.replace("_", " ") + function_details = function_details.replace("/", " -> ") + if function_details == "Biotype: Protein Coding": + function_details = function_details + ", Coding Region Unknown" + + #[snp_href, chr, mb_formatted, alleles, snp_source_cell, conservation_score, gene_name_cell, transcript_href, exon, domain_1, domain_2, function, function_details] + + base_color_dict = {"A": "#C33232", "C": "#1569C7", "T": "#CFCF32", "G": "#32C332", + "t": "#FF6", "c": "#5CB3FF", "a": "#F66", "g": "#CF9", ":": "#FFFFFF", "-": "#FFFFFF", "?": "#FFFFFF"} + + + the_bases = [] + for j, item in enumerate(allele_value_list): + if item: + this_base = [item, base_color_dict[item]] + else: + this_base = "" + + the_bases.append(this_base) + + this_row = { + "rs": rs, + "snp_url": snp_url, + "snp_name": snp_name, + "chr": chr, + "mb_formatted": mb_formatted, + "alleles": alleles, + "snp_source": snp_source, + "source_urls": source_urls, + "conservation_score": conservation_score, + "gene_name": gene_name, + "gene_link": gene_link, + "transcript": transcript, + "transcript_link": transcript_link, + "exon": exon, + "domain_1": domain_1, + "domain_2": domain_2, + "function": function, + "function_details": function_details, + "allele_value_list": the_bases + } + + elif self.variant_type == "InDel": + indel_name, indel_chr, indel_mb_s, indel_mb_e, indel_strand, indel_type, indel_size, indel_sequence, source_name = result + this_row = { + "indel_name": indel_name, + "indel_chr": indel_chr, + "indel_mb_s": indel_mb_s, + "indel_mb_e": indel_mb_e, + "indel_strand": indel_strand, + "indel_type": indel_type, + "indel_size": indel_size, + "indel_sequence": indel_sequence, + "source_name": source_name + } + #this_row = [indel_name, indel_chr, indel_mb_s, indel_mb_e, indel_strand, indel_type, indel_size, indel_sequence, source_name] + else: + this_row = {} + + the_rows.append(this_row) + + return the_rows + + def include_record(self, domain, function, snp_source, conservation_score): """ Decide whether to add this record """ @@ -304,7 +510,10 @@ class SnpBrowser(object): function_satisfied = False else: function_satisfied = False - if function.startswith(self.function): + if self.function != "All": + if function.startswith(self.function): + function_satisfied = True + else: function_satisfied = True else: if self.function != "All": @@ -358,23 +567,39 @@ class SnpBrowser(object): return domain_satisfied and function_satisfied and source_satisfied and score_satisfied and different_alleles_satisfied -def get_browser_sample_list(species_id=1): - sample_list = [] +def get_browser_sample_lists(species_id=1): + strain_lists = {} + mouse_strain_list = [] query = "SHOW COLUMNS FROM SnpPattern;" results = g.db.execute(query).fetchall(); for result in results[1:]: - sample_list.append(result[0]) + mouse_strain_list.append(result[0]) + + rat_strain_list = [] + query = "SHOW COLUMNS FROM RatSnpPattern;" + results = g.db.execute(query).fetchall(); + for result in results[2:]: + rat_strain_list.append(result[0]) + + strain_lists['mouse'] = mouse_strain_list + strain_lists['rat'] = rat_strain_list - return sample_list + return strain_lists -def get_header_list(variant_type, strain_list): +def get_header_list(variant_type, strains, species = None): + if species == "Mouse": + strain_list = strains['mouse'] + elif species == "Rat": + strain_list = strains['rat'] + else: + strain_list = strains + + header_fields = [] if variant_type == "SNP": - header_fields = ['Index', 'SNP ID', 'Chr', 'Mb', 'Alleles', 'Source', 'ConScore', 'Gene', 'Transcript', 'Exon', 'Domain 1', 'Domain 2', 'Function', 'Details'] - header_fields.extend(strain_list) + header_fields.append(['Index', 'SNP ID', 'Chr', 'Mb', 'Alleles', 'Source', 'ConScore', 'Gene', 'Transcript', 'Exon', 'Domain 1', 'Domain 2', 'Function', 'Details']) + header_fields.append(strain_list) elif variant_type == "InDel": header_fields = ['Index', 'ID', 'Type', 'InDel Chr', 'Mb Start', 'Mb End', 'Strand', 'Size', 'Sequence', 'Source'] - else: - header_fields = [] return header_fields @@ -454,7 +679,7 @@ def get_effect_info(effect_list): effect_detail_list = get_effect_details_by_category(effect_name='Splice Site', effect_value=splice_site) effect_info_dict[domain] = effect_detail_list if nonsplice_site: - domain = "Downstream" + domain = "Nonsplice Site" effect_detail_list = get_effect_details_by_category(effect_name='Nonsplice Site', effect_value=nonsplice_site) effect_info_dict[domain] = effect_detail_list # get gene, transcript_list, and exon info @@ -498,3 +723,29 @@ def get_effect_info(effect_list): effect_info_dict[domain] = effect_detail_list return effect_info_dict + +def get_gene_id_name_dict(gene_name_list): + gene_id_name_dict = {} + if len(gene_name_list) == 0: + return "" + gene_name_str_list = ["'" + gene_name + "'" for gene_name in gene_name_list] + gene_name_str = string.join(gene_name_str_list, ",") + + query = """ + SELECT + geneId, geneSymbol + FROM + GeneList + WHERE + SpeciesId = 1 AND geneSymbol in (%s) + """ % gene_name_str + + results = g.db.execute(query).fetchall() + + if len(results) > 0: + for item in results: + gene_id_name_dict[item[1]] = item[0] + else: + pass + + return gene_id_name_dict diff --git a/wqflask/wqflask/static/new/css/show_trait.css b/wqflask/wqflask/static/new/css/show_trait.css index 1e9fd4df..135a7643 100644 --- a/wqflask/wqflask/static/new/css/show_trait.css +++ b/wqflask/wqflask/static/new/css/show_trait.css @@ -8,4 +8,8 @@ tr .outlier { div.sample_group { overflow: auto; # needed because it contains float dataTable wrapper +} + +.js-plotly-plot .plotly .modebar { + left: 100px; }
\ No newline at end of file diff --git a/wqflask/wqflask/static/new/css/snp_browser.css b/wqflask/wqflask/static/new/css/snp_browser.css new file mode 100644 index 00000000..c1adaf20 --- /dev/null +++ b/wqflask/wqflask/static/new/css/snp_browser.css @@ -0,0 +1,22 @@ +.form_group { + margin-bottom 5px; +} + +table.dataTable thead th { + vertical-align: bottom; +} + +table.dataTable thead .sorting, +table.dataTable thead .sorting_asc, +table.dataTable thead .sorting_desc, +table.dataTable thead .sorting_asc_disabled, +table.dataTable thead .sorting_desc_disabled { + background-repeat: no-repeat; + background-position: bottom right; +} + +table.dataTable thead th{ + border-right: 1px solid white; + color: white; + background-color: royalblue; +}
\ No newline at end of file diff --git a/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot.js b/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot.js index be0b96a1..a74c99d3 100644 --- a/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot.js +++ b/wqflask/wqflask/static/new/javascript/draw_corr_scatterplot.js @@ -23,7 +23,8 @@ var layout = { visible: true, linecolor: 'black', linewidth: 1, - } + }, + hovermode: "closest" } cofactor1_dict = {} diff --git a/wqflask/wqflask/static/new/javascript/plotly_probability_plot.js b/wqflask/wqflask/static/new/javascript/plotly_probability_plot.js index ad06ff6a..1585b0ad 100644 --- a/wqflask/wqflask/static/new/javascript/plotly_probability_plot.js +++ b/wqflask/wqflask/static/new/javascript/plotly_probability_plot.js @@ -183,7 +183,8 @@ visible: true, linecolor: 'black', linewidth: 1, - } + }, + hovermode: "closest" } var primary_trace = { diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index a0a98437..a3edd0e6 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -776,6 +776,12 @@ sample_group_list = [js_data.sample_group_types['samples_primary']] } + // Define Plotly Options (for the options bar at the top of each figure) + + root.modebar_options = { + modeBarButtonsToRemove:['hoverClosest', 'hoverCompare', 'hoverClosestCartesian', 'hoverCompareCartesian', 'lasso2d', 'toggleSpikelines'] + } + // Bar Chart root.errors_exist = get_sample_errors(sample_lists[0])[1] @@ -822,7 +828,13 @@ range_bottom = 0 } } - if (get_sample_vals(sample_lists[0]).length < 256) { + + total_sample_count = 0 + for (i = 0, i < sample_lists.length; i++) { + total_sample_count += get_sample_vals(sample_lists[i]).length + } + + if (total_sample_count < 256) { bar_chart_width = 25 * get_sample_vals(sample_lists[0]).length var layout = { @@ -839,7 +851,7 @@ } }; root.bar_layout = layout - Plotly.newPlot('bar_chart', root.bar_data, root.bar_layout) + Plotly.newPlot('bar_chart', root.bar_data, root.bar_layout, root.modebar_options) } if (full_sample_lists.length > 1) { @@ -947,14 +959,14 @@ data: box_data, layout: root.box_layout } - Plotly.newPlot('box_plot', obj); + Plotly.newPlot('box_plot', obj, root.modebar_options); // Violin Plot if (full_sample_lists.length > 1) { root.violin_layout = { title: "Violin Plot", - xaxis: { + yaxis: { range: [range_bottom, range_top], zeroline: false }, @@ -963,12 +975,12 @@ margin: { l: 50, r: 30, - t: 30, + t: 80, b: 80 } }; var trace1 = { - x: get_sample_vals(full_sample_lists[2]), + y: get_sample_vals(full_sample_lists[2]), type: 'violin', points: 'none', box: { @@ -981,10 +993,10 @@ visible: true }, name: sample_group_list[2], - y0: sample_group_list[2] + x0: sample_group_list[2] } var trace2 = { - x: get_sample_vals(full_sample_lists[1]), + y: get_sample_vals(full_sample_lists[1]), type: 'violin', points: 'none', box: { @@ -997,10 +1009,10 @@ visible: true }, name: sample_group_list[1], - y0: sample_group_list[1] + x0: sample_group_list[1] } var trace3 = { - x: get_sample_vals(full_sample_lists[0]), + y: get_sample_vals(full_sample_lists[0]), type: 'violin', points: 'none', box: { @@ -1013,13 +1025,13 @@ visible: true }, name: sample_group_list[0], - y0: sample_group_list[0] + x0: sample_group_list[0] } violin_data = [trace1, trace2, trace3] } else { root.violin_layout = { title: "Violin Plot", - xaxis: { + yaxis: { range: [range_bottom, range_top], zeroline: false }, @@ -1028,13 +1040,13 @@ margin: { l: 50, r: 30, - t: 30, + t: 80, b: 80 } }; violin_data = [ { - x: get_sample_vals(full_sample_lists[0]), + y: get_sample_vals(full_sample_lists[0]), type: 'violin', points: 'none', box: { @@ -1047,7 +1059,7 @@ visible: true }, name: sample_group_list[0], - y0: sample_group_list[0] + x0: sample_group_list[0] } ] } @@ -1057,7 +1069,7 @@ layout: root.violin_layout } - Plotly.plot('violin_plot', obj) + Plotly.plot('violin_plot', obj, root.modebar_options) // Histogram var hist_trace = { @@ -1077,7 +1089,7 @@ b: 60 } }; - Plotly.newPlot('histogram', data, layout) + Plotly.newPlot('histogram', data, layout, root.modebar_options) update_histogram_width() diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index 3df4c81a..81c04db5 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -52,6 +52,9 @@ </a> </li> <li class=""> + <a href="/snp_browser">SNP Browser</a> + </li> + <li class=""> <a href="/help">Help</a> </li> <li class=""> diff --git a/wqflask/wqflask/templates/loading.html b/wqflask/wqflask/templates/loading.html index 43488c75..99fa4a89 100644 --- a/wqflask/wqflask/templates/loading.html +++ b/wqflask/wqflask/templates/loading.html @@ -1,6 +1,6 @@ <title>Loading Mapping Results</title> <link REL="stylesheet" TYPE="text/css" href="/static/packages/bootstrap/css/bootstrap.css" /> -<form method="post" action="/marker_regression" name="loading_form" id="loading_form" class="form-horizontal"> +<form method="post" action="/run_mapping" name="loading_form" id="loading_form" class="form-horizontal"> {% for key, value in start_vars.iteritems() %} <input type="hidden" name="{{ key }}" value="{{ value }}"> {% endfor %} diff --git a/wqflask/wqflask/templates/marker_regression_gn1.html b/wqflask/wqflask/templates/mapping_results.html index fd083983..5fb2c95e 100644 --- a/wqflask/wqflask/templates/marker_regression_gn1.html +++ b/wqflask/wqflask/templates/mapping_results.html @@ -10,7 +10,7 @@ {% from "base_macro.html" import header %} {% block content %} <div class="container"> - <form method="post" target="_blank" action="/marker_regression" name="marker_regression" id="marker_regression_form"> + <form method="post" target="_blank" action="/run_mapping" name="marker_regression" id="marker_regression_form"> <input type="hidden" name="temp_uuid" value="{{ temp_uuid }}"> <input type="hidden" name="trait_id" value="{{ this_trait.name }}"> <input type="hidden" name="dataset" value="{{ dataset.name }}"> diff --git a/wqflask/wqflask/templates/snp_browser.html b/wqflask/wqflask/templates/snp_browser.html index cbce1449..578bd2fc 100644 --- a/wqflask/wqflask/templates/snp_browser.html +++ b/wqflask/wqflask/templates/snp_browser.html @@ -9,9 +9,10 @@ <div class="container-fluid"> <h2>Variant Browser <a class="btn btn-primary" href="http://genenetwork.org/snpbrowser.html" role="button">Info</a></h2> - <div class="container" style="border-style: double; position: relative; width: 60%; padding-top: 10px; padding-right: 40px;"> + <div class="container" style="border-style: double; position: relative; width: 950px; padding-top: 10px; padding-right: 40px;"> <form id="snp_browser_form" method="get" action="/snp_browser"> - <input type="hidden" name="chosen_strains"> + <input type="hidden" name="chosen_strains_mouse" value="{{ chosen_strains_mouse|join(",") }}"> + <input type="hidden" name="chosen_strains_rat" value="{{ chosen_strains_rat|join(",") }}"> <div class="col-xs-4" style="padding-left: 0px;"> <div class="form-group row" style="margin-bottom: 5px;"> <label for="snp_or_indel" style="text-align: right;" class="col-xs-4 col-form-label"><b>Type:</b></label> @@ -25,17 +26,16 @@ <div class="form-group row" style="margin-bottom: 5px;"> <label for="species" style="text-align: right;" class="col-xs-4 col-form-label"><b>Species:</b></label> <div class="col-xs-8"> - <select name="species"> - <option value="Mouse" selected>Mouse</option> - <option value="Rat">Rat</option> - <option value="All" selected>All</option> + <select id="species_select" name="species"> + <option value="Mouse" {% if species_name == "Mouse" %}selected{% endif %}>Mouse</option> + <option value="Rat" {% if species_name == "Rat" %}selected{% endif %}>Rat</option> </select> </div> </div> <div class="form-group row" style="margin-bottom: 5px;"> <label for="gene_or_id" style="text-align: right;" class="col-xs-4 col-form-label"><b>Gene or ID:</b></label> <div class="col-xs-8"> - <input type="text" name="gene_name" size="12"> + <input type="text" name="gene_name" size="12" value="{{ gene_name }}"> </div> </div> <div class="form-group row"> @@ -75,15 +75,16 @@ <div class="form-group row" style="margin-bottom: 10px;"> <label for="strains" style="text-align: right;" class="col-xs-4 col-form-label"><b>Strains:</b></label> <div class="col-xs-8"> - <select name="strains" style="width: 70%;"> - <optgroup label="Mouse"> - {% for strain in strain_list[:-1] %} + <select id="strain_select" name="strains" style="width: 70%;"> + {% if species_name == "Mouse" %} + {% for strain in strain_lists['mouse'] %} <option value="{{ strain }}" {% if loop.index == 1 %}selected{% endif %}>{{ strain }}</option> {% endfor %} - </optgroup> - <optgroup label="Rat"> - <option value="BN">BN</option> - </optgroup> + {% elif species_name == "Rat" %} + {% for strain in strain_lists['rat'] %} + <option value="{{ strain }}" {% if loop.index == 1 %}selected{% endif %}>{{ strain }}</option> + {% endfor %} + {% endif %} </select> <div style="float: right; line-height: 20px;"> <input class="btn btn-primary" type="button" name="add_strain" value="Add" style="vertical-align: middle;"> @@ -177,32 +178,57 @@ </form> </div> + <div style="margin-top: 20px;"> {% if filtered_results is defined %} - <table class="cell-border nowrap" id="results_table" style="float: left;"> + {% if filtered_results|length > 5000 %} + There are more than 5000 results. Consider limiting your search to a smaller range. + {% else %} + <table class="dataTable cell-border nowrap" id="results_table" style="float: left;"> <thead> <tr> <th></th> + {% if header_fields|length == 2 %} + {% for header in header_fields[0] %} + <th data-export="{{ header }}">{{ header }}</th> + {% endfor %} + {% for strain in header_fields[1] %} + <th data-export="{{ strain }}" style="align: center; text-align: center; line-height: 15px;">{% for letter in strain %}<div style="transform: rotate(90deg);">{{ letter }}</div>{% endfor %}</th> + {% endfor %} + {% else %} {% for header in header_fields %} <th data-export="{{ header }}">{{ header }}</th> {% endfor %} + {% endif %} </tr> </thead> <tbody> - {% for result in filtered_results %} + {% for row in table_rows %} <tr> <td><input type="checkbox" name="trait_check"></td> <td align="right">{{ loop.index }}</td> - {% for item in result %} - {% if loop.index > 1 %} - <td>{{ item }}</td> - {% endif %} + <td>{% if row.rs != "" %}<b><a href="{{ row.snp_url }}">{{ row.snp_name }}</a></b>{% else %}<a href="{{ row.snp_url }}">{{ row.snp_name }}</a>{% endif %}</td> + <td>{{ row.chr }}</td> + <td>{{ row.mb_formatted }}</td> + <td>{{ row.alleles }}</td> + <td>{% if row.snp_source == "Sanger/UCLA" %}<a href="{{ row.source_urls[0] }}">Sanger</a>/<a href="{{ row.source_urls[1] }}">UCLA</a>{% else %}{{ row.snp_source }}{% endif %}</td> + <td>{{ row.conservation_score }}</td> + <td>{% if row.gene_name != "" %}<i>{{ row.gene_name }}</i><br><a href="{{ row.gene_link }}">NCBI</a>{% else %}{% endif %}</td> + <td><a href="{{ row.transcript_link }}">{{ row.transcript }}</a></td> + <td>{{ row.exon }}</td> + <td>{{ row.domain_1 }}</td> + <td>{{ row.domain_2 }}</td> + <td>{{ row.function }}</td> + <td>{{ row.function_details }}</td> + {% for item in row.allele_value_list %} + <td style="background-color: {{ item[1] }};">{{ item[0] }}</td> {% endfor %} </tr> {% endfor %} </tbody> </table> + {% endif %} {% endif %} - + </div> </div> {% endblock %} @@ -213,6 +239,18 @@ {% if filtered_results is defined %} $("#results_table").DataTable( { + {% if variant_type == "SNP" %} + "columnDefs": [ { + "targets": [0, {% for n in range(15, 15 + allele_list|length) %}, {{ n }}{% endfor %}], + "orderable": false + } ], + {% else %} + "columnDefs": [ { + "targets": 0, + "orderable": false + } ], + {% endif %} + "order": [[1, "asc" ]], "sDom": "tir", "iDisplayLength": -1, "autoWidth": true, @@ -220,14 +258,74 @@ }); {% endif %} + $("#species_select").change(function() { + this_species = $(this).val(); + $("#strain_select").empty() + $("#chosen_strains_select").empty() + + if (this_species == "Mouse") { + {% for strain in strain_lists["mouse"] %} + var option = $('<option></option>').attr("value", "{{ strain }}").text("{{ strain }}"); + $("select[name=strains]").append(option); + {% endfor %} + + chosen_strains = $("input[name=chosen_strains_mouse]").val().split(",") + } else if (this_species == "Rat") { + {% for strain in strain_lists["rat"] %} + var option = $('<option></option>').attr("value", "{{ strain }}").text("{{ strain }}"); + $("select[name=strains]").append(option); + {% endfor %} + + chosen_strains = $("input[name=chosen_strains_rat]").val().split(",") + } + + for (i=0; i < chosen_strains.length; i++) { + var option = $('<option></option>').attr("value", chosen_strains[i]).text(chosen_strains[i]); + $("#chosen_strains_select").append(option) + } + }); + $("input[name=add_strain]").click(function() { var selected_strain = $("select[name=strains] option:selected").val(); $("#chosen_strains_select").append("<option value='" + selected_strain + "'>" + selected_strain + "</option>"); + + var current_species = $("#species_select").val(); + if (current_species == "Mouse") { + stored_strains = $("input[name=chosen_strains_mouse]").val().split(",") + stored_strains.push(selected_strain) + $("input[name=chosen_strains_mouse]").val(stored_strains.join(",")) + } else if (current_species == "Rat") { + stored_strains = $("input[name=chosen_strains_rat]").val().split(",") + stored_strains.push(selected_strain) + $("input[name=chosen_strains_rat]").val(stored_strains.join(",")) + } }); $("input[name=remove_strain]").click(function() { var selected_strain = $("#chosen_strains_select option:selected").val(); $("#chosen_strains_select option[value='" + selected_strain + "']").remove(); + + var current_species = $("#species_select").val(); + + if (current_species == "Mouse") { + stored_strains = $("input[name=chosen_strains_mouse]").val().split(",") + for (i=0; i < stored_strains.length; i++) { + if (stored_strains[i] == selected_strain) { + stored_strains.splice(i, 1); + break; + } + } + $("input[name=chosen_strains_mouse]").val(stored_strains.join(",")) + } else if (current_species == "Rat") { + stored_strains = $("input[name=chosen_strains_rat]").val().split(",") + for (i=0; i < stored_strains.length; i++) { + if (stored_strains[i] == selected_strain) { + stored_strains.splice(i, 1); + break; + } + } + $("input[name=chosen_strains_rat]").val(stored_strains.join(",")) + } }); $("#snp_browser_form").submit(function() { diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index fdb80040..27e6eed1 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -44,8 +44,8 @@ from wqflask.show_trait import show_trait from wqflask.show_trait import export_trait_data from wqflask.heatmap import heatmap from wqflask.comparison_bar_chart import comparison_bar_chart -from wqflask.marker_regression import marker_regression -from wqflask.marker_regression import marker_regression_gn1 +from wqflask.marker_regression import run_mapping +from wqflask.marker_regression import display_mapping_results from wqflask.network_graph import network_graph from wqflask.correlation import show_corr_results from wqflask.correlation_matrix import show_corr_matrix @@ -551,10 +551,10 @@ def loading_page(): return rendered_template -@app.route("/marker_regression", methods=('POST',)) -def marker_regression_page(): +@app.route("/run_mapping", methods=('POST',)) +def mapping_results_page(): initial_start_vars = request.form - logger.debug("Marker regression called with initial_start_vars:", initial_start_vars.items()) + logger.debug("Mapping called with initial_start_vars:", initial_start_vars.items()) logger.info(request.url) temp_uuid = initial_start_vars['temp_uuid'] wanted = ( @@ -585,6 +585,7 @@ def marker_regression_page(): 'control_marker', 'control_marker_db', 'do_control', + 'genofile', 'genofile_string', 'pair_scan', 'startMb', @@ -606,10 +607,10 @@ def marker_regression_page(): for key, value in initial_start_vars.iteritems(): if key in wanted or key.startswith(('value:')): start_vars[key] = value - logger.debug("Marker regression called with start_vars:", start_vars) + logger.debug("Mapping called with start_vars:", start_vars) version = "v3" - key = "marker_regression:{}:".format(version) + json.dumps(start_vars, sort_keys=True) + key = "mapping_results:{}:".format(version) + json.dumps(start_vars, sort_keys=True) logger.info("key is:", pf(key)) with Bench("Loading cache"): result = None # Just for testing @@ -625,8 +626,8 @@ def marker_regression_page(): result = pickle.loads(result) else: logger.info("Cache miss!!!") - with Bench("Total time in MarkerRegression"): - template_vars = marker_regression.MarkerRegression(start_vars, temp_uuid) + with Bench("Total time in RunMapping"): + template_vars = run_mapping.RunMapping(start_vars, temp_uuid) if template_vars.mapping_method != "gemma" and template_vars.mapping_method != "plink": template_vars.js_data = json.dumps(template_vars.js_data, @@ -648,10 +649,7 @@ def marker_regression_page(): result['pair_scan_array'] = bytesarray rendered_template = render_template("pair_scan_results.html", **result) else: - #for item in template_vars.__dict__.keys(): - # logger.info(" ---**--- {}: {}".format(type(template_vars.__dict__[item]), item)) - - gn1_template_vars = marker_regression_gn1.MarkerRegression(result).__dict__ + gn1_template_vars = display_mapping_results.DisplayMappingResults(result).__dict__ #pickled_result = pickle.dumps(result, pickle.HIGHEST_PROTOCOL) #logger.info("pickled result length:", len(pickled_result)) #Redis.set(key, pickled_result) @@ -660,24 +658,7 @@ def marker_regression_page(): with Bench("Rendering template"): if (gn1_template_vars['mapping_method'] == "gemma") or (gn1_template_vars['mapping_method'] == "plink"): gn1_template_vars.pop('qtlresults', None) - print("TEMPLATE KEYS:", list(gn1_template_vars.keys())) - rendered_template = render_template("marker_regression_gn1.html", **gn1_template_vars) - - # with Bench("Rendering template"): - # if result['pair_scan'] == True: - # img_path = result['pair_scan_filename'] - # logger.info("img_path:", img_path) - # initial_start_vars = request.form - # logger.info("initial_start_vars:", initial_start_vars) - # imgfile = open(TEMPDIR + '/' + img_path, 'rb') - # imgdata = imgfile.read() - # imgB64 = imgdata.encode("base64") - # bytesarray = array.array('B', imgB64) - # result['pair_scan_array'] = bytesarray - # rendered_template = render_template("pair_scan_results.html", **result) - # else: - # rendered_template = render_template("marker_regression.html", **result) - # rendered_template = render_template("marker_regression_gn1.html", **gn1_template_vars) + rendered_template = render_template("mapping_results.html", **gn1_template_vars) return rendered_template @@ -693,7 +674,6 @@ def export_mapping_results(): return response - @app.route("/export", methods = ('POST',)) def export(): logger.info("request.form:", request.form) |