@@ -12,6 +12,7 @@ use serde_derive::Serialize;
1212use tera:: { self , Context , Tera } ;
1313
1414use crate :: bcf:: report:: table_report:: create_report_table:: get_ann_description;
15+ use crate :: bcf:: report:: table_report:: create_report_table:: read_tag_entries;
1516use chrono:: { DateTime , Local } ;
1617use jsonm:: packer:: { PackOptions , Packer } ;
1718use 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