22import os
33from multiprocessing import Pool
44
5- from math import ceil
5+ from math import ceil , floor
66import argparse
77import re
88import glob
@@ -67,6 +67,11 @@ def parse_args():
6767 type = int ,
6868 default = 3 ,
6969 help = "Minimum isoform size in terms of number supporting reads. Default {}" .format (3 ))
70+ parser .add_argument ("-mi" ,
71+ "--max-ilp" ,
72+ type = int ,
73+ default = 1500 ,
74+ help = "Maximum number of unique reads allowed for an ILP instance. ILP instances with more reads will have their input broken into evenly sized problems, each with less than the max. Default {}" .format (1500 ))
7075 parser .add_argument ("-to" ,
7176 "--timeout" ,
7277 type = int ,
@@ -99,6 +104,12 @@ def parse_args():
99104
100105 return args
101106
107+ def split_list_evenly (l , m ):
108+ p = ceil (len (l )/ m )
109+ s = ceil (len (l )/ p )
110+ for idx in range (0 , p * s , s ):
111+ yield l [idx :idx + s ]
112+
102113
103114def read_segment (segment_tsv ):
104115 tints = dict ()
@@ -136,9 +147,9 @@ def read_segment(segment_tsv):
136147 for p in poly_gap_prog .findall (re_dict ['gaps' ])},
137148 )
138149 read_rep_key = [d for d in re_dict ['data' ].replace ('2' , '0' )]
139- read_rep_key += ['.{}' .format (g [2 ] if int (g [2 ]) > 3 else 0 )
150+ read_rep_key += ['.{}' .format (g [2 ] if int (g [2 ]) > 10 else 0 )
140151 for g in internal_gap_prog .findall (re_dict ['gaps' ])]
141- read_rep_key += ['.{}{}' .format (p [0 ][0 ], p [2 ] if int (p [2 ]) > 3 else 0 )
152+ read_rep_key += ['.{}{}' .format (p [0 ][0 ], p [2 ] if int (p [2 ]) > 10 else 0 )
142153 for p in poly_gap_prog .findall (re_dict ['gaps' ])]
143154 read_rep_key = '' .join (read_rep_key )
144155 tind_id = read ['tint' ]
@@ -179,7 +190,7 @@ def garbage_cost_exons(I):
179190# TO DO: think about better ways to define the cost to assign to the garbagte isoform
180191
181192
182- def partition_reads (tint ):
193+ def partition_reads (tint , maximum_ilp_size ):
183194 reads = tint ['reads' ]
184195 read_reps = tint ['read_reps' ]
185196 I = tint ['ilp_data' ]['I' ]
@@ -229,18 +240,18 @@ def partition_reads(tint):
229240 for c in components .connected_components (G ):
230241 rids = list ()
231242 incomp = list ()
232- c = list (c )
233- for idx , i in enumerate (c ):
234- rids .extend (unique_data [i ][1 ])
235- # for j in c[idx+1:]:
236- # i,j = min(i,j),max(i,j)
237- # assert i<j
238- # if G.has_edge(i,j):
239- # continue
240- # for rid_1 in unique_data[i][1]:
241- # for rid_2 in unique_data[j][1]:
242- # incomp.append((rid_1,rid_2))
243- tint ['partitions' ].append ((rids , incomp ))
243+ for c in split_list_evenly ( list (c ), maximum_ilp_size ):
244+ for idx , i in enumerate (c ):
245+ rids .extend (unique_data [i ][1 ])
246+ for j in c [idx + 1 :]:
247+ i ,j = min (i ,j ),max (i ,j )
248+ assert i < j
249+ if G .has_edge (i ,j ):
250+ continue
251+ for rid_1 in unique_data [i ][1 ]:
252+ for rid_2 in unique_data [j ][1 ]:
253+ incomp .append ((rid_1 ,rid_2 ))
254+ tint ['partitions' ].append ((rids , incomp ))
244255
245256
246257def preprocess_ilp (tint , ilp_settings ):
@@ -684,7 +695,7 @@ def output_isoforms(tint, out_file):
684695 output .append (str ((reads [ridx ]['partition' ])))
685696 output .append (str ((reads [ridx ]['poly_tail_category' ])))
686697 output .append ('*' )
687- output .append ('*' )
698+ output .append ('' . join ( map ( str , reads [ ridx ][ 'data' ])) )
688699 exon_strs = [str (x ) for x in reads [ridx ]['data' ]]
689700 for (j1 , j2 ), l in reads [ridx ]['gaps' ].items ():
690701 exon_strs [j1 ] += '({})' .format (l )
@@ -702,6 +713,7 @@ def cluster_tint(cluster_args):
702713 tint_id ,
703714 ilp_settings ,
704715 min_isoform_size ,
716+ max_ilp ,
705717 logs_dir ,
706718 ) = cluster_args
707719 tints = read_segment (
@@ -715,7 +727,7 @@ def cluster_tint(cluster_args):
715727 timeout_log = open (
716728 '{}/{}/timeout.log' .format (logs_dir , tint ['id' ]), 'w+' )
717729 preprocess_ilp (tint , ilp_settings )
718- partition_reads (tint )
730+ partition_reads (tint , max_ilp )
719731 # print('# Paritions ({}) sizes: {}\n'.format(
720732 # len(tint['partitions']), [len(p) for p in tint['partitions']]))
721733 tint ['isoforms' ] = list ()
@@ -811,16 +823,17 @@ def main():
811823 tint_id ,
812824 ilp_settings ,
813825 args .min_isoform_size ,
826+ args .max_ilp ,
814827 '{}/{}' .format (args .logs_dir , contig ) if args .logs_dir != None else None ,
815828 ])
816829 if args .threads > 1 :
817830 p = Pool (args .threads )
818- for idx , tint_id in enumerate (p .imap_unordered (cluster_tint , cluster_args , chunksize = 5 )):
819- print ('[freddie_cluster] Done with {}/{} tints ({:.1%})' .format (idx ,
831+ for idx , tint_id in enumerate (p .imap_unordered (cluster_tint , cluster_args , chunksize = 1 )):
832+ print ('[freddie_cluster] Done with {}/{} tints ({:.1%})' .format (idx + 1 ,
820833 len (cluster_args ), idx / len (cluster_args )))
821834 else :
822835 for idx , tint_id in enumerate (map (cluster_tint , cluster_args )):
823- print ('[freddie_cluster] Done with {}/{} tints ({:.1%})' .format (idx ,
836+ print ('[freddie_cluster] Done with {}/{} tints ({:.1%})' .format (idx + 1 ,
824837 len (cluster_args ), idx / len (cluster_args )))
825838
826839
0 commit comments