Skip to content

Commit 32289bb

Browse files
Merge branch 'master' of github.com:rust-bio/rust-bio-tools
2 parents 2b27a57 + 74679e7 commit 32289bb

File tree

7 files changed

+274
-21
lines changed

7 files changed

+274
-21
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"type":"single",
3+
"empty":"none",
4+
"on":"mouseover",
5+
"fields":[
6+
"key"
7+
]
8+
}

src/bcf/report/info_specs.json

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"data":{
3+
"name":""
4+
},
5+
"mark":"bar",
6+
"width":100,
7+
"selection":{
8+
},
9+
"encoding":{
10+
"y":{
11+
"field":"key",
12+
"type":"ordinal",
13+
"sort": {},
14+
"axis": null
15+
},
16+
"x":{
17+
"field":"count",
18+
"aggregate":"sum",
19+
"stack": "normalize",
20+
"type":"quantitative",
21+
"axis":{
22+
"title":""
23+
}
24+
},
25+
"fillOpacity":{
26+
"condition":{
27+
"selection":"",
28+
"value":0.5
29+
},
30+
"value":1
31+
},
32+
"color":{
33+
"field":"value",
34+
"type":"nominal",
35+
"title":"existing variations",
36+
"scale":{
37+
"type":"ordinal"
38+
}
39+
}
40+
}
41+
}

src/bcf/report/js/report.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ vegaEmbed('#oncoprint', spec).then(function(result) {
5252
result.view.addEventListener('click', function(event, item) {
5353
if (item.datum.gene !== undefined || item.datum.key !== undefined) {
5454
if (item.datum.gene !== undefined ) {
55-
window.location.href = '../genes/' + item.datum.gene + '1.html';
55+
if (item.datum.gene.startsWith("ENST") && item.datum.sample !== undefined) {
56+
window.location.href = '../details/' + item.datum.sample + '/' + item.datum.gene + '.html';
57+
} else {
58+
window.location.href = '../genes/' + item.datum.gene + '1.html';
59+
}
5660
} else {
5761
window.location.href = '../genes/' + item.datum.key + '1.html';
5862
}
@@ -61,7 +65,7 @@ vegaEmbed('#oncoprint', spec).then(function(result) {
6165
});
6266
});
6367

64-
window.addEventListener('resize', function(event){
68+
window.addEventListener('resize', function(event) {
6569
let page_width = $(window).width();
6670
let matrix_width = Math.min(page_width - 740, samples*20);
6771
if (matrix_width < 20 && samples >= 2) {
@@ -84,7 +88,11 @@ window.addEventListener('resize', function(event){
8488
result.view.addEventListener('click', function(event, item) {
8589
if (item.datum.gene !== undefined || item.datum.key !== undefined) {
8690
if (item.datum.gene !== undefined ) {
87-
window.location.href = '../genes/' + item.datum.gene + '1.html';
91+
if (item.datum.gene.startsWith("ENST") && item.datum.sample !== undefined) {
92+
window.location.href = '../details/' + item.datum.sample + '/' + item.datum.gene + '.html';
93+
} else {
94+
window.location.href = '../genes/' + item.datum.gene + '1.html';
95+
}
8896
} else {
8997
window.location.href = '../genes/' + item.datum.key + '1.html';
9098
}

src/bcf/report/oncoprint.rs

Lines changed: 174 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use serde_derive::Serialize;
1212
use tera::{self, Context, Tera};
1313

1414
use crate::bcf::report::table_report::create_report_table::get_ann_description;
15+
use crate::bcf::report::table_report::create_report_table::read_tag_entries;
1516
use chrono::{DateTime, Local};
1617
use jsonm::packer::{PackOptions, Packer};
1718
use rust_htslib::bcf::{self, Read};
@@ -29,6 +30,7 @@ pub fn oncoprint(
2930
output_path: &str,
3031
max_cells: u32,
3132
tsv_data_path: Option<&str>,
33+
plot_info: Option<Vec<String>>,
3234
) -> Result<(), Box<dyn Error>> {
3335
let mut data = HashMap::new();
3436
let mut gene_data = HashMap::new();
@@ -43,6 +45,8 @@ pub fn oncoprint(
4345
let mut af_data = Vec::new();
4446
let mut gene_af_data = HashMap::new();
4547
let mut unique_genes = HashMap::new();
48+
let mut plot_info_data = HashMap::new();
49+
let mut gene_plot_info_data = HashMap::new();
4650

4751
let tsv_data = if let Some(tsv) = tsv_data_path {
4852
Some(make_tsv_records(tsv.to_owned())?)
@@ -78,6 +82,9 @@ pub fn oncoprint(
7882
let mut clin_sigs = HashMap::new();
7983
let mut gene_clin_sigs = HashMap::new();
8084
let mut ann_indices = HashMap::new();
85+
let mut pi_data = HashMap::new();
86+
let mut gene_pi_data = HashMap::new();
87+
8188
let mut bcf_reader = bcf::Reader::from_path(path)?;
8289
let header = bcf_reader.header().clone();
8390
let mut sample_names = Vec::new();
@@ -97,7 +104,7 @@ pub fn oncoprint(
97104

98105
for res in bcf_reader.records() {
99106
let mut gene_data_per_record = HashMap::new();
100-
let record = res?;
107+
let mut record = res?;
101108
let alleles = record
102109
.alleles()
103110
.into_iter()
@@ -108,6 +115,13 @@ pub fn oncoprint(
108115
let dup = [ref_allele.clone(), ref_allele.clone()].concat();
109116
let rev = ref_allele.clone().into_iter().rev().collect_vec();
110117

118+
let mut info_map = HashMap::new();
119+
if plot_info.is_some() {
120+
for tag in &plot_info.clone().unwrap() {
121+
read_tag_entries(&mut info_map, &mut record, &header, tag)?;
122+
}
123+
}
124+
111125
let allel_frequencies = record
112126
.format(b"AF")
113127
.float()?
@@ -159,8 +173,11 @@ pub fn oncoprint(
159173
get_field("SYMBOL")?
160174
} else if !get_field("Gene")?.is_empty() {
161175
get_field("Gene")?
176+
} else if !get_field("HGVSg")?.is_empty() {
177+
warn!("Warning! Found allele in {:?} without SYMBOL or Gene field. Using HGVSg instead.", record);
178+
get_field("HGVSg")?
162179
} else {
163-
warn!("Warning! Found allele in {:?} without SYMBOL or Gene field. This record will be skipped!", record);
180+
warn!("Warning! Found allele in {:?} without SYMBOL, Gene or HGVSg field. This record will be skipped!", record);
164181
continue;
165182
};
166183
let dna_alteration = get_field("HGVSg")?;
@@ -214,6 +231,52 @@ pub fn oncoprint(
214231
protein_alteration
215232
};
216233

234+
if plot_info.is_some() {
235+
for key in plot_info.clone().unwrap() {
236+
let info = info_map.get(&key.clone());
237+
if info.is_none() {
238+
let e = pi_data.entry(key.clone()).or_insert_with(HashMap::new);
239+
let rec = e.entry(gene.to_owned()).or_insert_with(Vec::new);
240+
rec.push(BarPlotRecord::new(
241+
gene.to_owned(),
242+
"unknown".to_string(),
243+
));
244+
let e2 = gene_pi_data
245+
.entry(key.clone())
246+
.or_insert_with(HashMap::new);
247+
let rec2 = e2.entry(gene.to_owned()).or_insert_with(Vec::new);
248+
rec2.push(BarPlotRecord::new(
249+
alt.to_owned(),
250+
"unknown".to_string(),
251+
));
252+
} else {
253+
for val in info.unwrap() {
254+
let value = if val == &json!("") || val == &json!(".") {
255+
"unknown".to_string()
256+
} else {
257+
val.to_string().trim_matches('\"').to_owned()
258+
};
259+
let e =
260+
pi_data.entry(key.clone()).or_insert_with(HashMap::new);
261+
let rec = e.entry(gene.to_owned()).or_insert_with(Vec::new);
262+
rec.push(BarPlotRecord::new(
263+
gene.to_owned(),
264+
value.clone(),
265+
));
266+
let e2 = gene_pi_data
267+
.entry(key.clone())
268+
.or_insert_with(HashMap::new);
269+
let rec2 =
270+
e2.entry(gene.to_owned()).or_insert_with(Vec::new);
271+
rec2.push(BarPlotRecord::new(
272+
alt.to_owned(),
273+
value.clone(),
274+
));
275+
}
276+
}
277+
}
278+
}
279+
217280
let split_ev = existing_var.split('&').collect_vec();
218281
for ex_var in split_ev {
219282
let mut ev: String =
@@ -317,6 +380,14 @@ pub fn oncoprint(
317380
let final_evs = make_final_bar_plot_records(ex_var);
318381
existing_var_data.push(final_evs);
319382

383+
for (tag, map) in pi_data.clone() {
384+
if let Some(t_data) = map.get(gene) {
385+
let final_data = make_final_bar_plot_records(t_data);
386+
let e = plot_info_data.entry(tag).or_insert_with(Vec::new);
387+
e.push(final_data);
388+
}
389+
}
390+
320391
let consequence = consequences.get(gene).unwrap();
321392
let final_consequences = make_final_bar_plot_records(consequence);
322393
consequence_data.push(final_consequences);
@@ -334,6 +405,15 @@ pub fn oncoprint(
334405
.or_insert_with(Vec::new);
335406
e.push(final_gene_impacts);
336407

408+
for (tag, map) in gene_pi_data.clone() {
409+
if let Some(t_data) = map.get(gene) {
410+
let final_data = make_final_bar_plot_records(t_data);
411+
let m = gene_plot_info_data.entry(tag).or_insert_with(HashMap::new);
412+
let e = m.entry(gene.to_owned()).or_insert_with(Vec::new);
413+
e.push(final_data);
414+
}
415+
}
416+
337417
let gene_evs = gene_existing_variations.get(gene).unwrap();
338418
let final_gene_evs = make_final_bar_plot_records(gene_evs);
339419
let v = gene_existing_var_data
@@ -393,6 +473,13 @@ pub fn oncoprint(
393473
let final_impact: Vec<_> = impact_data.iter().flatten().sorted().collect();
394474
let existing_var_data = gene_existing_var_data.get(&gene).unwrap();
395475
let final_ev: Vec<_> = existing_var_data.iter().flatten().sorted().collect();
476+
let mut inf_plot_data = HashMap::new();
477+
for (tag, data) in &gene_plot_info_data {
478+
if let Some(d) = data.get(&gene) {
479+
let final_data: Vec<_> = d.iter().flatten().sorted().collect();
480+
inf_plot_data.insert(tag.to_owned(), final_data.clone());
481+
}
482+
}
396483
let consequence_data = gene_consequence_data.get(&gene).unwrap();
397484
let final_consequence: Vec<_> = consequence_data.iter().flatten().sorted().collect();
398485
let clin_sig_data = gene_clin_sig_data.get(&gene).unwrap();
@@ -473,6 +560,18 @@ pub fn oncoprint(
473560
.filter(|entry| sorted_alterations.contains(&&&entry.key))
474561
.collect();
475562

563+
let mut info_page_data = HashMap::new();
564+
if plot_info.is_some() {
565+
for (tag, data) in inf_plot_data.clone() {
566+
info_page_data.insert(
567+
tag,
568+
data.into_iter()
569+
.filter(|entry| sorted_alterations.contains(&&&entry.record.key))
570+
.collect_vec(),
571+
);
572+
}
573+
}
574+
476575
let order: Vec<_> = ordered_alts
477576
.iter()
478577
.filter(|gene| sorted_alterations.contains(gene))
@@ -487,18 +586,46 @@ pub fn oncoprint(
487586
json!({ "main": page_data, "impact": impact_page_data, "ev": ev_page_data, "consequence": consequence_page_data, "allel_frequency": af_page_data})
488587
};
489588

589+
if plot_info.is_some() {
590+
for (tag, data) in info_page_data {
591+
values[tag] = json!(data);
592+
}
593+
}
594+
490595
if let Some(ref tsv) = tsv_data {
491596
for (title, data) in tsv {
492597
values[title] = json!(data);
493598
}
494599
}
600+
495601
specs["datasets"] = values;
496602
if !cs_present_folded {
497603
let hconcat = specs["vconcat"][1]["hconcat"].as_array_mut().unwrap();
498604
hconcat.remove(4);
499605
specs["vconcat"][1]["hconcat"] = json!(hconcat);
500606
}
501607

608+
if plot_info.is_some() {
609+
let info_specs: Value =
610+
serde_json::from_str(include_str!("info_specs.json")).unwrap();
611+
let highlight_specs: Value =
612+
serde_json::from_str(include_str!("highlight_specs.json")).unwrap();
613+
let hconcat = specs["vconcat"][1]["hconcat"].as_array_mut().unwrap();
614+
for tag in plot_info_data.keys() {
615+
let mut tag_specs = info_specs.clone();
616+
tag_specs["data"] = json!({ "name": tag });
617+
let highlight_name = "highlight_".to_string() + tag;
618+
tag_specs["selection"] = json!({ &highlight_name: highlight_specs });
619+
tag_specs["encoding"]["color"]["title"] = json!(tag);
620+
tag_specs["encoding"]["x"]["title"] = json!(tag);
621+
tag_specs["encoding"]["fillOpacity"]["condition"]["selection"] =
622+
json!(highlight_name);
623+
hconcat.push(tag_specs);
624+
}
625+
626+
specs["vconcat"][1]["hconcat"] = json!(hconcat);
627+
}
628+
502629
if let Some(ref tsv) = tsv_data {
503630
let tsv_specs: Value =
504631
serde_json::from_str(include_str!("tsv_specs.json")).unwrap();
@@ -554,6 +681,12 @@ pub fn oncoprint(
554681
let ev_data: Vec<_> = existing_var_data.iter().flatten().collect();
555682
let consequence_data: Vec<_> = consequence_data.iter().flatten().collect();
556683
let clin_sig_data: Vec<_> = clin_sig_data.iter().flatten().collect();
684+
let mut i_plot_data = HashMap::new();
685+
if plot_info.is_some() {
686+
for (tag, data) in plot_info_data.clone() {
687+
i_plot_data.insert(tag, data.into_iter().flatten().collect_vec());
688+
}
689+
}
557690

558691
let sorted_impacts = order_by_impact(impact_data.clone());
559692
let sorted_clin_sigs = order_by_clin_sig(clin_sig_data.clone());
@@ -682,6 +815,18 @@ pub fn oncoprint(
682815
.filter(|entry| sorted_genes.contains(&&entry.key))
683816
.collect();
684817

818+
let mut info_page_data = HashMap::new();
819+
if plot_info.is_some() {
820+
for (tag, data) in i_plot_data.clone() {
821+
info_page_data.insert(
822+
tag,
823+
data.into_iter()
824+
.filter(|entry| sorted_genes.contains(&&entry.record.key))
825+
.collect_vec(),
826+
);
827+
}
828+
}
829+
685830
let order: Vec<_> = ordered_genes
686831
.iter()
687832
.filter(|gene| sorted_genes.contains(gene))
@@ -699,6 +844,12 @@ pub fn oncoprint(
699844
json!({ "main": page_data, "impact": impact_page_data, "ev": ev_page_data, "consequence": consequence_page_data, "allel_frequency": af_page_data})
700845
};
701846

847+
if plot_info.is_some() {
848+
for (tag, data) in info_page_data {
849+
values[tag] = json!(data);
850+
}
851+
}
852+
702853
if let Some(ref tsv) = tsv_data {
703854
for (title, data) in tsv {
704855
values[title] = json!(data);
@@ -712,6 +863,27 @@ pub fn oncoprint(
712863
vl_specs["vconcat"][1]["hconcat"] = json!(hconcat);
713864
}
714865

866+
if plot_info.is_some() {
867+
let info_specs: Value =
868+
serde_json::from_str(include_str!("info_specs.json")).unwrap();
869+
let highlight_specs: Value =
870+
serde_json::from_str(include_str!("highlight_specs.json")).unwrap();
871+
let hconcat = vl_specs["vconcat"][1]["hconcat"].as_array_mut().unwrap();
872+
for tag in plot_info_data.keys() {
873+
let mut tag_specs = info_specs.clone();
874+
tag_specs["data"] = json!({ "name": tag });
875+
let highlight_name = "highlight_".to_string() + tag;
876+
tag_specs["selection"] = json!({ &highlight_name: highlight_specs });
877+
tag_specs["encoding"]["color"]["title"] = json!(tag);
878+
tag_specs["encoding"]["x"]["title"] = json!(tag);
879+
tag_specs["encoding"]["fillOpacity"]["condition"]["selection"] =
880+
json!(highlight_name);
881+
hconcat.push(tag_specs);
882+
}
883+
884+
vl_specs["vconcat"][1]["hconcat"] = json!(hconcat);
885+
}
886+
715887
if let Some(ref tsv) = tsv_data {
716888
let tsv_specs: Value =
717889
serde_json::from_str(include_str!("tsv_specs.json")).unwrap();

0 commit comments

Comments
 (0)