@@ -9,7 +9,7 @@ use std::collections::HashMap;
99use std:: error:: Error ;
1010use std:: fs:: File ;
1111use std:: io:: { BufRead , BufReader } ;
12- use std:: path:: PathBuf ;
12+ use std:: path:: { Path , PathBuf } ;
1313
1414// Add this function to generate consistent colors for segment names
1515fn get_segment_color ( segment_name : & str ) -> & ' static str {
@@ -105,7 +105,7 @@ pub struct PlotterArgs {
105105 output : Option < PathBuf > ,
106106}
107107
108- fn generate_plot_coverage ( input_directory : & PathBuf ) -> Result < Plot , Box < dyn Error > > {
108+ fn generate_plot_coverage ( input_directory : & Path ) -> Result < Plot , Box < dyn Error > > {
109109 // Create a Plotly plot
110110 let mut plot = Plot :: new ( ) ;
111111
@@ -162,7 +162,7 @@ fn generate_plot_coverage(input_directory: &PathBuf) -> Result<Plot, Box<dyn Err
162162
163163 // Set the figure title
164164 let layout = Layout :: new ( )
165- . title ( & format ! (
165+ . title ( format ! (
166166 "Coverage | {}" ,
167167 input_directory
168168 . file_name( )
@@ -193,69 +193,67 @@ fn generate_plot_coverage(input_directory: &PathBuf) -> Result<Plot, Box<dyn Err
193193 Ok ( plot)
194194}
195195
196- fn generate_plot_coverage_seg ( input_directory : & PathBuf ) -> Result < Plot , Box < dyn Error > > {
196+ fn generate_plot_coverage_seg ( input_directory : & Path ) -> Result < Plot , Box < dyn Error > > {
197197 // Init a Plotly plot
198198 let mut plot = Plot :: new ( ) ;
199199
200200 // Track number of files for subplot layout
201201 let mut file_paths = Vec :: new ( ) ;
202202
203203 // First, count files and collect paths
204- for entry in glob ( & format ! (
204+ let tmp = glob ( & format ! (
205205 "{}/tables/*coverage.txt" ,
206206 input_directory. display( )
207- ) ) ? {
208- if let Ok ( path) = entry {
209- //file_count += 1;
210- file_paths. push ( path) ;
211- }
207+ ) ) ?;
208+ for path in tmp. flatten ( ) {
209+ //file_count += 1;
210+ file_paths. push ( path) ;
212211 }
213212
214213 // Calculate grid dimensions for subplots
215214 let rows = 4 ; //((file_count + 2) as f64).sqrt().ceil() as usize;
216215 let cols = 2 ; //(file_count + rows - 1) / rows; // Ceiling division
217216
218217 // Load variant data into a HashMap keyed by segment name
218+ // todo: fix this type
219+ #[ allow( clippy:: type_complexity) ]
219220 let mut variants_data: HashMap < String , Vec < ( u32 , String , String , u32 , u32 , f32 ) > > =
220221 HashMap :: new ( ) ;
221222
222223 // Look for variant files with matching prefixes in the directory
223- for entry in glob ( & format ! (
224+ let tmp1 = glob ( & format ! (
224225 "{}/tables/*variants.txt" ,
225226 input_directory. display( )
226- ) ) ? {
227- if let Ok ( variant_path) = entry {
228- let file = File :: open ( & variant_path) ?;
229-
230- // Create a TSV reader
231- let mut rdr = ReaderBuilder :: new ( )
232- . delimiter ( b'\t' )
233- . has_headers ( true )
234- . from_reader ( file) ;
235-
236- for result in rdr. records ( ) {
237- let record = result?;
238- if record. len ( ) >= 8 {
239- let segment_name = record[ 0 ] . to_string ( ) ;
240- let position: u32 = record[ 1 ] . parse ( ) ?;
241- let consensus_allele: String = record[ 3 ] . to_string ( ) ;
242- let minority_allele: String = record[ 4 ] . to_string ( ) ;
243- let consensus_count: u32 = record[ 5 ] . parse ( ) ?;
244- let minority_count: u32 = record[ 6 ] . parse ( ) ?;
245- let minority_frequency: f32 = record[ 8 ] . parse ( ) ?;
246-
247- variants_data
248- . entry ( segment_name)
249- . or_insert_with ( Vec :: new)
250- . push ( (
251- position,
252- consensus_allele,
253- minority_allele,
254- consensus_count,
255- minority_count,
256- minority_frequency,
257- ) ) ;
258- }
227+ ) ) ?;
228+ let tmp2 = tmp1;
229+ for variant_path in tmp2. flatten ( ) {
230+ let file = File :: open ( & variant_path) ?;
231+
232+ // Create a TSV reader
233+ let mut rdr = ReaderBuilder :: new ( )
234+ . delimiter ( b'\t' )
235+ . has_headers ( true )
236+ . from_reader ( file) ;
237+
238+ for result in rdr. records ( ) {
239+ let record = result?;
240+ if record. len ( ) >= 8 {
241+ let segment_name = record[ 0 ] . to_string ( ) ;
242+ let position: u32 = record[ 1 ] . parse ( ) ?;
243+ let consensus_allele: String = record[ 3 ] . to_string ( ) ;
244+ let minority_allele: String = record[ 4 ] . to_string ( ) ;
245+ let consensus_count: u32 = record[ 5 ] . parse ( ) ?;
246+ let minority_count: u32 = record[ 6 ] . parse ( ) ?;
247+ let minority_frequency: f32 = record[ 8 ] . parse ( ) ?;
248+
249+ variants_data. entry ( segment_name) . or_default ( ) . push ( (
250+ position,
251+ consensus_allele,
252+ minority_allele,
253+ consensus_count,
254+ minority_count,
255+ minority_frequency,
256+ ) ) ;
259257 }
260258 }
261259 }
@@ -356,7 +354,7 @@ fn generate_plot_coverage_seg(input_directory: &PathBuf) -> Result<Plot, Box<dyn
356354 // Create trace for minority values with consistent color (but with transparency)
357355 let minority_trace = Scatter :: new ( variant_positions, minority_values)
358356 . mode ( Mode :: Markers )
359- . name ( & format ! ( "{}" , segment_name) )
357+ . name ( & segment_name)
360358 . marker (
361359 plotly:: common:: Marker :: new ( )
362360 . color ( segment_color)
@@ -383,7 +381,7 @@ fn generate_plot_coverage_seg(input_directory: &PathBuf) -> Result<Plot, Box<dyn
383381 . columns ( cols)
384382 . pattern ( GridPattern :: Independent ) ,
385383 )
386- . title ( & format ! (
384+ . title ( format ! (
387385 "Segment Coverage | {}" ,
388386 input_directory
389387 . file_name( )
@@ -472,7 +470,7 @@ fn generate_plot_coverage_seg(input_directory: &PathBuf) -> Result<Plot, Box<dyn
472470}
473471
474472// TO DO: fix colors for Sankey diagram
475- fn generate_sankey_plot ( input_directory : & PathBuf ) -> Result < Plot , Box < dyn Error > > {
473+ fn generate_sankey_plot ( input_directory : & Path ) -> Result < Plot , Box < dyn Error > > {
476474 // Path to READ_COUNTS.txt
477475 let read_counts_path = input_directory. join ( "tables" ) . join ( "READ_COUNTS.txt" ) ;
478476
@@ -505,7 +503,8 @@ fn generate_sankey_plot(input_directory: &PathBuf) -> Result<Plot, Box<dyn Error
505503
506504 // Process data and build node map first
507505 let mut records = Vec :: new ( ) ;
508- for line in lines {
506+
507+ lines. for_each ( |line| {
509508 if let Ok ( line) = line {
510509 let parts: Vec < & str > = line. split ( '\t' ) . collect ( ) ;
511510 if parts. len ( ) >= 3 {
@@ -518,7 +517,7 @@ fn generate_sankey_plot(input_directory: &PathBuf) -> Result<Plot, Box<dyn Error
518517 }
519518 }
520519 }
521- }
520+ } ) ;
522521
523522 // Add initial nodes
524523 add_node (
@@ -573,10 +572,9 @@ fn generate_sankey_plot(input_directory: &PathBuf) -> Result<Plot, Box<dyn Error
573572 "3-nomatch" => no_match = * reads,
574573 "3-chimeric" | "3-altmatch" => chi_alt_reads += * reads,
575574 _ => {
576- if record. starts_with ( "4-" ) {
575+ if let Some ( stripped ) = record. strip_prefix ( "4-" ) {
577576 primary_match_sum += * reads;
578- let segment = record[ 2 ..] . to_string ( ) ;
579- four_segments. push ( ( segment, * reads) ) ;
577+ four_segments. push ( ( stripped. to_string ( ) , * reads) )
580578 }
581579 }
582580 }
@@ -615,19 +613,17 @@ fn generate_sankey_plot(input_directory: &PathBuf) -> Result<Plot, Box<dyn Error
615613
616614 // Now process 5- records as before
617615 for ( record, reads) in & records {
618- if record. starts_with ( "5-" ) {
619- let segment = record[ 2 ..] . to_string ( ) ;
620- let segment_color = get_segment_color ( & segment) ;
616+ if let Some ( segment) = record. strip_prefix ( "5-" ) {
617+ let segment_color = get_segment_color ( segment) ;
621618 add_node (
622- & segment,
619+ segment,
623620 & mut node_labels,
624621 & mut node_map,
625622 & mut node_colors,
626623 segment_color,
627624 ) ;
628- // Link from Alt Match to this segment
629625 source_indices. push ( node_map[ "Alt Match" ] ) ;
630- target_indices. push ( node_map[ & segment] ) ;
626+ target_indices. push ( node_map[ segment] ) ;
631627 values. push ( * reads) ;
632628 }
633629 }
@@ -733,7 +729,7 @@ fn generate_sankey_plot(input_directory: &PathBuf) -> Result<Plot, Box<dyn Error
733729
734730 // Set layout
735731 let layout = Layout :: new ( )
736- . title ( & format ! (
732+ . title ( format ! (
737733 "Read Assignment | {}" ,
738734 input_directory
739735 . file_name( )
0 commit comments