2121
2222import argparse
2323import math
24- from moddotplot .static_plots import read_df_from_file , create_plots
24+ from moddotplot .static_plots import read_df_from_file , create_plots , create_grid
2525import json
2626import numpy as np
2727import pickle
@@ -342,6 +342,12 @@ def get_parser():
342342 help = "Plot comparative plots in an NxN grid like format." ,
343343 )
344344
345+ static_parser .add_argument (
346+ "--grid-only" ,
347+ action = "store_true" ,
348+ help = "Plot comparative plots in an NxN grid like format, skipping individual plots" ,
349+ )
350+
345351 # TODO: Implement static mode logging options
346352
347353 return parser
@@ -428,6 +434,13 @@ def main():
428434 args .bin_freq = config .get ("bin_freq" , args .bin_freq )
429435
430436 # TODO: Include logging options here
437+ # Check if conflicitng command line args
438+ if args .grid or args .grid_only :
439+ if not (args .compare or args .compare_only ) and not args .bed :
440+ print (
441+ f"Option --grid was selected, but no comparative plots will be produced. Please rerun ModDotPlot with the `--compare` or `--compare-only` option.\n "
442+ )
443+ sys .exit (10 )
431444
432445 # -----------INPUT COMMAND VALIDATION-----------
433446 # TODO: More tests!
@@ -447,65 +460,100 @@ def main():
447460
448461 # -----------BEDFILE INPUT FOR STATIC MODE-----------
449462 if hasattr (args , "bed" ) and args .bed :
463+ if args .grid or args .grid_only :
464+ single_vals = []
465+ double_vals = []
466+ single_val_name = []
467+ double_val_name = []
450468 try :
451469 for bed in args .bed :
452470 # If args.bed is provided as input, run static mode directly from the bed file. Skip counting input k-mers.
453471 df = read_df_from_file (bed )
472+
454473 unique_query_names = df ["#query_name" ].unique ()
455474 unique_reference_names = df ["reference_name" ].unique ()
456475 assert len (unique_query_names ) == len (unique_reference_names )
457476 # TODO: Change this to allow for multiple seqs in bed file
458477 assert len (unique_reference_names ) == 1
459478 self_id_scores = df [df ["#query_name" ] == df ["reference_name" ]]
460479 pairwise_id_scores = df [df ["#query_name" ] != df ["reference_name" ]]
461- print (
462- f"Input bed file { bed } read successfully! Creating plots... \n "
463- )
480+ if not args .grid_only :
481+ print (
482+ f"Input bed file { bed } read successfully! Creating plots... \n "
483+ )
464484 # Create directory
465485 if not args .output_dir :
466486 args .output_dir = os .getcwd ()
467487 if not os .path .exists (args .output_dir ):
468488 os .makedirs (args .output_dir )
469489 if len (self_id_scores ) > 1 :
470- create_plots (
471- sdf = None ,
472- directory = args .output_dir if args .output_dir else "." ,
473- name_x = unique_query_names [0 ],
474- name_y = unique_query_names [0 ],
475- palette = args .palette ,
476- palette_orientation = args .palette_orientation ,
477- no_hist = args .no_hist ,
478- width = args .width ,
479- dpi = args .dpi ,
480- is_freq = args .bin_freq ,
481- xlim = args .axes_limits ,
482- custom_colors = args .colors ,
483- custom_breakpoints = args .breakpoints ,
484- from_file = df ,
485- is_pairwise = False ,
486- axes_labels = args .axes_ticks ,
487- )
490+ if not args .grid_only :
491+ create_plots (
492+ sdf = None ,
493+ directory = args .output_dir if args .output_dir else "." ,
494+ name_x = unique_query_names [0 ],
495+ name_y = unique_query_names [0 ],
496+ palette = args .palette ,
497+ palette_orientation = args .palette_orientation ,
498+ no_hist = args .no_hist ,
499+ width = args .width ,
500+ dpi = args .dpi ,
501+ is_freq = args .bin_freq ,
502+ xlim = args .axes_limits ,
503+ custom_colors = args .colors ,
504+ custom_breakpoints = args .breakpoints ,
505+ from_file = df ,
506+ is_pairwise = False ,
507+ axes_labels = args .axes_ticks ,
508+ )
509+ if args .grid or args .grid_only :
510+ single_vals .append (df )
511+ single_val_name .append (unique_query_names [0 ])
488512 # Case 2: Pairwise bed file
489513 if len (pairwise_id_scores ) > 1 :
490- create_plots (
491- sdf = None ,
492- directory = args .output_dir if args .output_dir else "." ,
493- name_x = unique_query_names [0 ],
494- name_y = unique_reference_names [0 ],
495- palette = args .palette ,
496- palette_orientation = args .palette_orientation ,
497- no_hist = args .no_hist ,
498- width = args .width ,
499- dpi = args .dpi ,
500- is_freq = args .bin_freq ,
501- xlim = args .axes_limits , # TODO: Get xlim working
502- custom_colors = args .colors ,
503- custom_breakpoints = args .breakpoints ,
504- from_file = df ,
505- is_pairwise = True ,
506- axes_labels = args .axes_ticks ,
507- )
514+ if not args .grid_only :
515+ create_plots (
516+ sdf = None ,
517+ directory = args .output_dir if args .output_dir else "." ,
518+ name_x = unique_query_names [0 ],
519+ name_y = unique_reference_names [0 ],
520+ palette = args .palette ,
521+ palette_orientation = args .palette_orientation ,
522+ no_hist = args .no_hist ,
523+ width = args .width ,
524+ dpi = args .dpi ,
525+ is_freq = args .bin_freq ,
526+ xlim = args .axes_limits ,
527+ custom_colors = args .colors ,
528+ custom_breakpoints = args .axes_ticks ,
529+ from_file = df ,
530+ is_pairwise = True ,
531+ axes_labels = args .axes_ticks ,
532+ )
533+ if args .grid or args .grid_only :
534+ double_vals .append (df )
535+ double_val_name .append (
536+ [unique_query_names [0 ], unique_reference_names [0 ]]
537+ )
508538 # Exit once all bed files have been iterated through
539+ if args .grid or args .grid_only :
540+ print (f"Creating a { len (sequences )} x{ len (sequences )} grid.\n " )
541+ create_grid (
542+ singles = single_vals ,
543+ doubles = double_vals ,
544+ directory = args .output_dir if args .output_dir else "." ,
545+ palette = args .palette ,
546+ palette_orientation = args .palette_orientation ,
547+ no_hist = args .no_hist ,
548+ single_names = single_val_name ,
549+ double_names = double_val_name ,
550+ is_freq = args .bin_freq ,
551+ xlim = args .axes_limits ,
552+ custom_colors = args .colors ,
553+ custom_breakpoints = args .axes_ticks ,
554+ axes_label = args .axes_ticks ,
555+ is_bed = True ,
556+ )
509557 sys .exit (0 )
510558 except Exception as e :
511559 # Exit code 7: Error getting info from bed file:
@@ -531,7 +579,6 @@ def main():
531579 for i in args .fasta :
532580 kmer_list .append (readKmersFromFile (i , args .kmer , False ))
533581 k_list = [item for sublist in kmer_list for item in sublist ]
534-
535582 # Throw error if compare only selected with one sequence.
536583 if len (k_list ) < 2 and args .compare_only :
537584 print (
@@ -817,8 +864,12 @@ def main():
817864 # -----------SETUP STATIC MODE-----------
818865 elif args .command == "static" :
819866 # -----------SET SPARSITY VALUE-----------
820- # TODO: this is not sorting correctly
867+ if args .grid or args .grid_only :
868+ grid_val_singles = []
869+ grid_val_single_names = []
821870 sequences = list (zip (seq_list , k_list ))
871+ if len (sequences ) > 6 and (args .grid or args .grid_only ):
872+ print ("Too many sequences to create a grid. Skipping. \n " )
822873
823874 # Create output directory, if doesn't exist:
824875 if (args .output_dir ) and not os .path .exists (args .output_dir ):
@@ -884,6 +935,9 @@ def main():
884935 bed = convertMatrixToBed (
885936 self_mat , win , args .identity , seq_list [i ], seq_list [i ], True
886937 )
938+ if args .grid or args .grid_only :
939+ grid_val_singles .append (bed )
940+ grid_val_single_names .append (sequences [i ][0 ])
887941
888942 if not args .no_bed :
889943 # Log saving bed file
@@ -923,8 +977,9 @@ def main():
923977 if (args .compare or args .compare_only ) and len (sequences ) > 1 :
924978 # Set window size to args.window. Otherwise, set it to n/resolution
925979
926- if args .grid :
927- grid_vals = []
980+ if args .grid or args .grid_only :
981+ grid_val_doubles = []
982+ grid_val_double_names = []
928983
929984 for i in range (len (sequences )):
930985 for j in range (i + 1 , len (sequences )):
@@ -987,7 +1042,7 @@ def main():
9871042 expectation ,
9881043 )
9891044 # Throw error if the matrix is empty
990- if np .all (pair_mat == 0 ):
1045+ if np .all (pair_mat == 0 ) and ( not ( args . grid or args . grid_only )) :
9911046 print (
9921047 f"The pairwise identity matrix for { sequences [i ][0 ]} and { sequences [j ][0 ]} is empty. Skipping.\n "
9931048 )
@@ -1000,8 +1055,11 @@ def main():
10001055 seq_list [j ],
10011056 False ,
10021057 )
1003- if args .grid :
1004- grid_vals .append (bed )
1058+ if args .grid or args .grid_only :
1059+ grid_val_doubles .append (bed )
1060+ grid_val_double_names .append (
1061+ [larger_seq_name , smaller_seq_name ]
1062+ )
10051063
10061064 if not args .no_bed :
10071065 # Log saving bed file
@@ -1045,8 +1103,24 @@ def main():
10451103 axes_labels = args .axes_ticks ,
10461104 )
10471105
1048- """if args.grid:
1049- print(grid_vals)"""
1106+ if args .grid or args .grid_only :
1107+ print (f"Creating a { len (sequences )} x{ len (sequences )} grid.\n " )
1108+ create_grid (
1109+ singles = grid_val_singles ,
1110+ doubles = grid_val_doubles ,
1111+ directory = args .output_dir if args .output_dir else "." ,
1112+ palette = args .palette ,
1113+ palette_orientation = args .palette_orientation ,
1114+ no_hist = args .no_hist ,
1115+ single_names = grid_val_single_names ,
1116+ double_names = grid_val_double_names ,
1117+ is_freq = args .bin_freq ,
1118+ xlim = args .axes_limits ,
1119+ custom_colors = args .colors ,
1120+ custom_breakpoints = args .axes_ticks ,
1121+ axes_label = args .axes_ticks ,
1122+ is_bed = False ,
1123+ )
10501124
10511125
10521126if __name__ == "__main__" :
0 commit comments