GPatch 0.3.1__tar.gz → 0.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {GPatch-0.3.1 → GPatch-0.3.4}/PKG-INFO +1 -1
- {GPatch-0.3.1 → GPatch-0.3.4}/setup.py +10 -4
- GPatch-0.3.4/src/GPatch/GPatch.py +331 -0
- GPatch-0.3.4/src/GPatch/__init__.py +0 -0
- GPatch-0.3.4/src/GPatch/__main__.py +11 -0
- {GPatch-0.3.1 → GPatch-0.3.4/src}/GPatch.egg-info/PKG-INFO +1 -1
- GPatch-0.3.4/src/GPatch.egg-info/SOURCES.txt +17 -0
- GPatch-0.3.4/src/GPatch.egg-info/top_level.txt +3 -0
- GPatch-0.3.1/GPatch.egg-info/SOURCES.txt +0 -15
- GPatch-0.3.1/GPatch.egg-info/top_level.txt +0 -1
- {GPatch-0.3.1 → GPatch-0.3.4}/CODE_OF_CONDUCT.md +0 -0
- {GPatch-0.3.1 → GPatch-0.3.4}/LICENSE +0 -0
- {GPatch-0.3.1 → GPatch-0.3.4}/MANIFEST.in +0 -0
- {GPatch-0.3.1 → GPatch-0.3.4}/README.md +0 -0
- {GPatch-0.3.1 → GPatch-0.3.4}/pyproject.toml +0 -0
- {GPatch-0.3.1 → GPatch-0.3.4}/requirements.txt +0 -0
- {GPatch-0.3.1 → GPatch-0.3.4}/setup.cfg +0 -0
- {GPatch-0.3.1 → GPatch-0.3.4/src}/GPatch.egg-info/dependency_links.txt +0 -0
- {GPatch-0.3.1 → GPatch-0.3.4/src}/GPatch.egg-info/entry_points.txt +0 -0
- {GPatch-0.3.1 → GPatch-0.3.4/src}/GPatch.egg-info/not-zip-safe +0 -0
- {GPatch-0.3.1 → GPatch-0.3.4/src}/GPatch.egg-info/requires.txt +0 -0
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import sys
|
|
2
|
+
from glob import glob
|
|
3
|
+
from os.path import basename, splitext
|
|
4
|
+
from pathlib import Path
|
|
2
5
|
|
|
3
6
|
if sys.version_info > (3, ) and sys.version_info < (3, 7):
|
|
4
7
|
sys.exit("ERROR: GPatch requires Python 3.7 or greater")
|
|
5
8
|
|
|
9
|
+
package_dir = {'':'src'}
|
|
6
10
|
try:
|
|
7
11
|
from setuptools import setup, find_packages
|
|
8
12
|
except ImportError:
|
|
@@ -25,14 +29,18 @@ def main():
|
|
|
25
29
|
|
|
26
30
|
metadata = dict(
|
|
27
31
|
name="GPatch",
|
|
28
|
-
version="0.3.
|
|
32
|
+
version="0.3.4",
|
|
29
33
|
author="Adam Diehl",
|
|
30
34
|
author_email="adadiehl@umich.edu",
|
|
31
35
|
description="Assemble contigs into a chromosome-scalse pseudo-assembly using alignments to a reference sequence.",
|
|
32
36
|
long_description=readme(),
|
|
33
37
|
long_description_content_type="text/markdown",
|
|
34
38
|
url="https://github.com/adadiehl/GPatch",
|
|
35
|
-
packages = find_packages(),
|
|
39
|
+
packages = find_packages('src'),
|
|
40
|
+
package_dir = {'':'src'},
|
|
41
|
+
py_modules = [splitext(basename(path))[0] for path in glob('src/GPatch/*.py')],
|
|
42
|
+
include_package_data = True,
|
|
43
|
+
zip_safe = False,
|
|
36
44
|
package_data = {
|
|
37
45
|
'GPatch': [
|
|
38
46
|
"LICENSE",
|
|
@@ -63,8 +71,6 @@ def main():
|
|
|
63
71
|
"Natural Language :: English"
|
|
64
72
|
],
|
|
65
73
|
keywords = "genomics, genome assembly",
|
|
66
|
-
include_package_data=True,
|
|
67
|
-
zip_safe=False,
|
|
68
74
|
)
|
|
69
75
|
|
|
70
76
|
setup(**metadata)
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
import sys, os, re
|
|
4
|
+
from argparse import ArgumentParser
|
|
5
|
+
from Bio import SeqIO
|
|
6
|
+
from Bio.Seq import Seq
|
|
7
|
+
import pysam
|
|
8
|
+
import random
|
|
9
|
+
|
|
10
|
+
__version__ = "0.3.4"
|
|
11
|
+
|
|
12
|
+
"""
|
|
13
|
+
Given a name-sorted BAM file, cluster mapped reads by name and
|
|
14
|
+
use the maximal interval defined by the primary alignment's
|
|
15
|
+
cigar string to infer the contig break-points in the reference
|
|
16
|
+
genome.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def create_primary_alignments_list(query_bam, min_qual_score):
|
|
20
|
+
"""
|
|
21
|
+
Extract all primary alignments from the BAM file and return
|
|
22
|
+
as a list.
|
|
23
|
+
"""
|
|
24
|
+
ret = []
|
|
25
|
+
for aln in query_bam:
|
|
26
|
+
if aln.is_unmapped:
|
|
27
|
+
# Skip unmapped contigs
|
|
28
|
+
continue
|
|
29
|
+
if aln.mapping_quality < min_qual_score:
|
|
30
|
+
# Skip low-quality mappings
|
|
31
|
+
continue
|
|
32
|
+
if not (aln.is_supplementary or aln.is_secondary):
|
|
33
|
+
ret.append(aln)
|
|
34
|
+
return ret
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def contig_breakpoints_from_cigar(primary_alignments):
|
|
38
|
+
"""
|
|
39
|
+
Infer the contig breakpoints using soft-clips on the primary
|
|
40
|
+
alignments.
|
|
41
|
+
"""
|
|
42
|
+
contig_breakpoints = {}
|
|
43
|
+
for contig in primary_alignments:
|
|
44
|
+
# Default to mapped coordinates
|
|
45
|
+
chrom = contig.reference_name
|
|
46
|
+
start = contig.reference_start
|
|
47
|
+
end = contig.reference_end
|
|
48
|
+
# Check for left and right soft-clips
|
|
49
|
+
if contig.cigartuples[0][0] == 4:
|
|
50
|
+
# left soft-clip
|
|
51
|
+
start -= contig.cigartuples[0][1]
|
|
52
|
+
if contig.cigartuples[-1][0] == 4:
|
|
53
|
+
# right soft-clip
|
|
54
|
+
end += contig.cigartuples[-1][1]
|
|
55
|
+
contig_breakpoints[contig.query_name] = [chrom, start, end, contig.query_name]
|
|
56
|
+
|
|
57
|
+
return contig_breakpoints
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def sorted_bam_from_aln_list(aln_list, bam_header, sorted_bam_name=None):
|
|
61
|
+
"""
|
|
62
|
+
Given a list of pysam AlignedSegment objects, sort by position with
|
|
63
|
+
a pysam system call. Returns the name of the sorted file.
|
|
64
|
+
"""
|
|
65
|
+
tmp_root = ''.join(random.sample('0123456789', 10))
|
|
66
|
+
tmp_bam_name = tmp_root + '.tmp.bam'
|
|
67
|
+
if sorted_bam_name is None:
|
|
68
|
+
sorted_bam_name = tmp_root + '.tmp.sorted.bam'
|
|
69
|
+
tmp_bam = pysam.AlignmentFile(tmp_bam_name, "wb", header=bam_header)
|
|
70
|
+
for aln in aln_list:
|
|
71
|
+
tmp_bam.write(aln)
|
|
72
|
+
tmp_bam.close()
|
|
73
|
+
pysam.sort("-o", sorted_bam_name, tmp_bam_name)
|
|
74
|
+
os.remove(tmp_bam_name)
|
|
75
|
+
return sorted_bam_name
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def whitelist_filter(sorted_alignments_bam, whitelist, sorted_bam_name=None):
|
|
79
|
+
"""
|
|
80
|
+
Given a sorted BAM file, use a system call to SAMTools to
|
|
81
|
+
extract only alignments overlapping intervals within the
|
|
82
|
+
whitelist BED.
|
|
83
|
+
"""
|
|
84
|
+
tmp_root = ''.join(random.sample('0123456789', 10))
|
|
85
|
+
tmp_bam_name = tmp_root + '.tmp.bam'
|
|
86
|
+
if sorted_bam_name is None:
|
|
87
|
+
sorted_bam_name = tmp_root + '.tmp.sorted.bam'
|
|
88
|
+
# Because pysam.view is buggy about creating output files with -o, we need
|
|
89
|
+
# to touch the output file before calling pysam view.
|
|
90
|
+
pb = open(tmp_bam_name, 'w')
|
|
91
|
+
pb.close()
|
|
92
|
+
pysam.view("-L", whitelist, "-h", "-b", "-o", tmp_bam_name, sorted_alignments_bam, catch_stdout=False)
|
|
93
|
+
# Sort and index the result. Not sure if this is really necessary,
|
|
94
|
+
# since input is already sorted. In principle, sort order may not be
|
|
95
|
+
# maintainted, though -- not sure this is guaranteed.
|
|
96
|
+
pysam.sort("-o", sorted_bam_name, tmp_bam_name)
|
|
97
|
+
pysam.index(sorted_bam_name)
|
|
98
|
+
os.remove(tmp_bam_name)
|
|
99
|
+
return sorted_bam_name
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def contigs_to_sorted_interval_list(contigs, contig_breakpoints):
|
|
103
|
+
"""
|
|
104
|
+
Given an iterator over contig alignments from pysam.fetch,
|
|
105
|
+
generate a list of intervals, sorted on position. Alignments are
|
|
106
|
+
assumed to be on the same chromosome.
|
|
107
|
+
"""
|
|
108
|
+
# Push contig alignment space start, end, and name to a list
|
|
109
|
+
ints = []
|
|
110
|
+
for contig in contigs:
|
|
111
|
+
start = contig_breakpoints[contig.query_name][1]
|
|
112
|
+
end = contig_breakpoints[contig.query_name][2]
|
|
113
|
+
name = contig.query_name
|
|
114
|
+
ints.append((start, end, name))
|
|
115
|
+
# Sort the list by position
|
|
116
|
+
ret = sorted(ints, key=lambda x: (x[0], x[1]))
|
|
117
|
+
return ret
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def cluster_contig_positions(sorted_contig_intervals, drop_nested=False):
|
|
121
|
+
"""
|
|
122
|
+
Given a list of contig intervals, sorted on start then end
|
|
123
|
+
position, cluster intervals based on linear overlap and
|
|
124
|
+
return a list of clusters, optionally leaving out any nested
|
|
125
|
+
intervals.
|
|
126
|
+
"""
|
|
127
|
+
clusters = []
|
|
128
|
+
for contig in sorted_contig_intervals:
|
|
129
|
+
#sys.stderr.write("{0}\n".format(contig))
|
|
130
|
+
merged = False
|
|
131
|
+
for cluster in clusters:
|
|
132
|
+
#sys.stderr.write("\t%s\n" % (cluster))
|
|
133
|
+
if contig[0] <= cluster[-1][1]:
|
|
134
|
+
if drop_nested:
|
|
135
|
+
if not contig[1] <= cluster[-1][1]:
|
|
136
|
+
cluster.append(contig)
|
|
137
|
+
else:
|
|
138
|
+
#sys.stderr.write("\tnested\n")
|
|
139
|
+
pass
|
|
140
|
+
else:
|
|
141
|
+
cluster.append(contig)
|
|
142
|
+
#sys.stderr.write("\tmerged\n")
|
|
143
|
+
merged = True
|
|
144
|
+
break
|
|
145
|
+
if not merged:
|
|
146
|
+
clusters.append([contig])
|
|
147
|
+
return clusters
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def main():
|
|
151
|
+
parser = ArgumentParser(description="Starting with alignments of contigs to a reference genome, produce a chromosome-scale pseudoassembly by patching gaps between mapped contigs with sequences from the reference.")
|
|
152
|
+
parser.add_argument('-q', '--query_bam', metavar='SAM/BAM', type=str,
|
|
153
|
+
required=True, help='Path to SAM/BAM file containing non-overlapping contig mappings to the reference genome.')
|
|
154
|
+
parser.add_argument('-r', '--reference_fasta', metavar='FASTA', type=str,
|
|
155
|
+
required=True, help='Path to reference genome fasta.')
|
|
156
|
+
parser.add_argument('-x', '--prefix', metavar='STR', type=str,
|
|
157
|
+
required=False, default="",
|
|
158
|
+
help='Prefix to add to output file names. Default=None')
|
|
159
|
+
parser.add_argument('-b', '--store_final_bam', metavar='FILENAME', type=str,
|
|
160
|
+
required=False, default=None,
|
|
161
|
+
help='Store the final set of primary contig alignments to the given file name. Default: Do not store the final BAM.')
|
|
162
|
+
parser.add_argument('-m', '--min_qual_score', metavar='N', type=int,
|
|
163
|
+
required=False, default=30,
|
|
164
|
+
help='Minimum mapping quality score to retain an alignment. Default=30')
|
|
165
|
+
parser.add_argument('-w', '--whitelist', metavar='PATH', type=str,
|
|
166
|
+
required=False, default=None,
|
|
167
|
+
help='Path to BED file containing whitelist regions: i.e., the inverse of blacklist regions. Supplying this will have the effect of excluding alignments that fall entirely within blacklist regions. Default=None')
|
|
168
|
+
parser.add_argument('-d', '--drop_missing', type=bool,
|
|
169
|
+
required=False, default=False,
|
|
170
|
+
help='Omit unpatched reference chromosome records from the output if no contigs map to them. Default: Unpatched chromosomes are printed to output unchanged.')
|
|
171
|
+
|
|
172
|
+
args = parser.parse_args()
|
|
173
|
+
|
|
174
|
+
query_bam = pysam.AlignmentFile(args.query_bam)
|
|
175
|
+
|
|
176
|
+
# Load up the BAM into a dict, keyed on contig name.
|
|
177
|
+
sys.stderr.write("Loading alignments...\n")
|
|
178
|
+
primary_alignments = create_primary_alignments_list(query_bam, args.min_qual_score)
|
|
179
|
+
|
|
180
|
+
# Determine insertion break-points for each contig based
|
|
181
|
+
# on the cigar string for the primary alignment.
|
|
182
|
+
sys.stderr.write("Locating contig breakpoints...\n")
|
|
183
|
+
contig_breakpoints = contig_breakpoints_from_cigar(primary_alignments)
|
|
184
|
+
|
|
185
|
+
# Sort the useful primary alignments by position via pysam sort.
|
|
186
|
+
sys.stderr.write("Sorting primary alignments...\n")
|
|
187
|
+
sorted_primary_alignments_bam = sorted_bam_from_aln_list(primary_alignments, query_bam.header, sorted_bam_name=args.store_final_bam)
|
|
188
|
+
pysam.index(sorted_primary_alignments_bam)
|
|
189
|
+
|
|
190
|
+
# Exclude alignments entirely within blacklist regions if requested.
|
|
191
|
+
if args.whitelist is not None:
|
|
192
|
+
sys.stderr.write("Filtering against the whitelist...\n")
|
|
193
|
+
filtered_bam = whitelist_filter(sorted_primary_alignments_bam, args.whitelist)
|
|
194
|
+
# Swap the filtered bam in for the sorted primary alignments bam
|
|
195
|
+
os.remove(sorted_primary_alignments_bam)
|
|
196
|
+
os.remove(sorted_primary_alignments_bam + ".bai")
|
|
197
|
+
os.rename(filtered_bam, sorted_primary_alignments_bam)
|
|
198
|
+
os.rename(filtered_bam + '.bai', sorted_primary_alignments_bam + ".bai")
|
|
199
|
+
|
|
200
|
+
# Check for nested/overlapping alignment spaces among the remaining contigs.
|
|
201
|
+
sys.stderr.write("Checking for nested or overlapping contigs...\n")
|
|
202
|
+
sorted_primary_alignments = pysam.AlignmentFile(sorted_primary_alignments_bam, "rb")
|
|
203
|
+
final_alignments = []
|
|
204
|
+
for ref_seq in SeqIO.parse(args.reference_fasta, "fasta"):
|
|
205
|
+
# Select all contigs mapped to this sequence.
|
|
206
|
+
contigs = list(sorted_primary_alignments.fetch(ref_seq.id))
|
|
207
|
+
|
|
208
|
+
# Convert the list of contigs into a list of tuples: (start, end, name),
|
|
209
|
+
# representing the inferred contig breakpoints, sorted by start, then end position.
|
|
210
|
+
sorted_contig_intervals = contigs_to_sorted_interval_list(contigs, contig_breakpoints)
|
|
211
|
+
|
|
212
|
+
# Cluster the linear intervals on overlap, leaving out nested contigs
|
|
213
|
+
clusters = cluster_contig_positions(sorted_contig_intervals, drop_nested=True)
|
|
214
|
+
|
|
215
|
+
# Next thing to do is to push all retained contigs across clusters into
|
|
216
|
+
# a final list of useful contigs. Since pysam.fetch does not allow
|
|
217
|
+
# retrieval by alignment name, the easiest way to do this is through a
|
|
218
|
+
# dict of names that will allow us to make a single pass through the
|
|
219
|
+
# contig list to select what we need.
|
|
220
|
+
retained_alignments = {}
|
|
221
|
+
for cluster in clusters:
|
|
222
|
+
for interval in cluster:
|
|
223
|
+
retained_alignments[interval[2]] = interval
|
|
224
|
+
for contig in contigs:
|
|
225
|
+
if contig.query_name in retained_alignments:
|
|
226
|
+
final_alignments.append(contig)
|
|
227
|
+
|
|
228
|
+
sorted_primary_alignments.close()
|
|
229
|
+
|
|
230
|
+
# Write the final set of alignments to a sorted BAM file
|
|
231
|
+
sorted_primary_alignments_bam = sorted_bam_from_aln_list(final_alignments, query_bam.header, sorted_bam_name=args.store_final_bam)
|
|
232
|
+
pysam.index(sorted_primary_alignments_bam)
|
|
233
|
+
|
|
234
|
+
# Set up output streams for fasta, patches.bed, and contigs.bed
|
|
235
|
+
sys.stderr.write("Patching the genome...\n")
|
|
236
|
+
pf_fname = "patched.fasta"
|
|
237
|
+
pb_fname = "patches.bed"
|
|
238
|
+
cb_fname = "contigs.bed"
|
|
239
|
+
if args.prefix != "":
|
|
240
|
+
pf_fname = args.prefix + '.' + pf_fname
|
|
241
|
+
pb_fname = args.prefix + '.' + pb_fname
|
|
242
|
+
cb_fname = args.prefix + '.' + cb_fname
|
|
243
|
+
patched_fasta = open(pf_fname, "w") # Patched fasta
|
|
244
|
+
patches_bed = open(pb_fname, "w") # Reference-frame patch coordinates
|
|
245
|
+
contigs_bed = open(cb_fname, "w") # Patched genome frame contig coordinates
|
|
246
|
+
|
|
247
|
+
# Open up the sorted primary alignments bam for reading.
|
|
248
|
+
sorted_primary_alignments = pysam.AlignmentFile(sorted_primary_alignments_bam, "rb")
|
|
249
|
+
|
|
250
|
+
for ref_seq in SeqIO.parse(args.reference_fasta, "fasta"):
|
|
251
|
+
# Select all contigs mapped to this sequence.
|
|
252
|
+
contigs = list(sorted_primary_alignments.fetch(ref_seq.id))
|
|
253
|
+
|
|
254
|
+
# If no contigs map to this sequence, either print it unchanged
|
|
255
|
+
# or omit it, depending on args.
|
|
256
|
+
if len(contigs) == 0:
|
|
257
|
+
if args.drop_missing:
|
|
258
|
+
sys.stderr.write("No contigs map to %s. Omitting from output.\n" % (ref_seq.id))
|
|
259
|
+
else:
|
|
260
|
+
sys.stderr.write("No contigs map to %s. Printing the reference sequence to output unchanged.\n" % (ref_seq.id))
|
|
261
|
+
patched_fasta.write("%s\n" % (ref_seq.format("fasta")))
|
|
262
|
+
continue
|
|
263
|
+
|
|
264
|
+
pos = 0 # Tracks position on the reference chromosome
|
|
265
|
+
patched_seq = ""
|
|
266
|
+
for contig in contigs:
|
|
267
|
+
rstart = contig_breakpoints[contig.query_name][1]
|
|
268
|
+
if rstart > 0:
|
|
269
|
+
rstart -= 1
|
|
270
|
+
|
|
271
|
+
# Check for overlapping/bookended contig mappings.
|
|
272
|
+
qstart = 0 # Start of contig interval to append
|
|
273
|
+
if rstart > pos:
|
|
274
|
+
# No overlap. Append the patch, in all lower-case
|
|
275
|
+
# for easy identification.
|
|
276
|
+
patched_seq = patched_seq + ref_seq.seq[pos:rstart].lower()
|
|
277
|
+
# Write patch coordinates in reference frame to patches_bed
|
|
278
|
+
patches_bed.write("%s\t%d\t%d\n" % (ref_seq.id, pos, rstart))
|
|
279
|
+
else:
|
|
280
|
+
# Handle overlapping contig ends by trimming the 5' end of
|
|
281
|
+
# this contig sequence by the length of the overlap.
|
|
282
|
+
qstart = pos - rstart
|
|
283
|
+
|
|
284
|
+
# Append the contig sequence to the patched sequence string
|
|
285
|
+
contig_start = len(patched_seq)
|
|
286
|
+
# All patch sequences are printed in upper case.
|
|
287
|
+
# Overlaps with the previous contig are handled by truncating
|
|
288
|
+
# the 3' end of this contig sequence.
|
|
289
|
+
patched_seq = patched_seq + Seq(contig.query_sequence)[qstart:len(Seq(contig.query_sequence))].upper()
|
|
290
|
+
|
|
291
|
+
# Gather what we need to write BED coordinates for this contig
|
|
292
|
+
qstrand = "+"
|
|
293
|
+
if contig.is_reverse:
|
|
294
|
+
# Since BAM sequence is already reverse-complemented, we don't have to!
|
|
295
|
+
qstrand = "-"
|
|
296
|
+
|
|
297
|
+
# Write contig coordinates in patched-genome frame to contigs_bed
|
|
298
|
+
contigs_bed.write("%s\t%d\t%d\t%s\t.\t%s\t%d\t%d\n" % (ref_seq.id, contig_start, len(patched_seq), contig.query_name, qstrand, qstart, len(Seq(contig.query_sequence))))
|
|
299
|
+
|
|
300
|
+
# Update the current position in the reference sequence if the
|
|
301
|
+
# end position of the current contig is 3' of the current pos.
|
|
302
|
+
if contig_breakpoints[contig.query_name][2] > pos:
|
|
303
|
+
# This should always evaluate true in the absence of nested contigs.
|
|
304
|
+
pos = contig_breakpoints[contig.query_name][2]
|
|
305
|
+
|
|
306
|
+
# Once the above loop finishes, we need to add the terminal segment
|
|
307
|
+
# from the reference genome.
|
|
308
|
+
patched_seq = patched_seq + ref_seq.seq[pos:len(ref_seq.seq)]
|
|
309
|
+
patches_bed.write("%s\t%d\t%d\n" % (ref_seq.id, pos, len(ref_seq.seq)))
|
|
310
|
+
|
|
311
|
+
# Swap in the patched sequence for the reference sequence and print the result
|
|
312
|
+
ref_seq.seq = patched_seq
|
|
313
|
+
patched_fasta.write("%s\n" % (ref_seq.format("fasta")))
|
|
314
|
+
|
|
315
|
+
# Close open file handles, etc.
|
|
316
|
+
query_bam.close()
|
|
317
|
+
sorted_primary_alignments.close()
|
|
318
|
+
patched_fasta.close()
|
|
319
|
+
patches_bed.close()
|
|
320
|
+
contigs_bed.close()
|
|
321
|
+
|
|
322
|
+
# Clean up any leftover files as needed.
|
|
323
|
+
if args.store_final_bam is None:
|
|
324
|
+
os.remove(sorted_primary_alignments_bam)
|
|
325
|
+
os.remove(sorted_primary_alignments_bam + '.bai')
|
|
326
|
+
|
|
327
|
+
sys.stderr.write("Done!\n")
|
|
328
|
+
|
|
329
|
+
if __name__ == '__main__':
|
|
330
|
+
main()
|
|
331
|
+
exit(0)
|
|
File without changes
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Entrypoint module, in case you use `python -mnameless`.
|
|
3
|
+
Why does this file exist, and why __main__? For more info, read:
|
|
4
|
+
- https://www.python.org/dev/peps/pep-0338/
|
|
5
|
+
- https://docs.python.org/2/using/cmdline.html#cmdoption-m
|
|
6
|
+
- https://docs.python.org/3/using/cmdline.html#cmdoption-m
|
|
7
|
+
"""
|
|
8
|
+
from GPatch.GPatch import main
|
|
9
|
+
|
|
10
|
+
if __name__ == "__main__":
|
|
11
|
+
main()
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
MANIFEST.in
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
setup.py
|
|
5
|
+
./CODE_OF_CONDUCT.md
|
|
6
|
+
./LICENSE
|
|
7
|
+
./requirements.txt
|
|
8
|
+
src/GPatch/GPatch.py
|
|
9
|
+
src/GPatch/__init__.py
|
|
10
|
+
src/GPatch/__main__.py
|
|
11
|
+
src/GPatch.egg-info/PKG-INFO
|
|
12
|
+
src/GPatch.egg-info/SOURCES.txt
|
|
13
|
+
src/GPatch.egg-info/dependency_links.txt
|
|
14
|
+
src/GPatch.egg-info/entry_points.txt
|
|
15
|
+
src/GPatch.egg-info/not-zip-safe
|
|
16
|
+
src/GPatch.egg-info/requires.txt
|
|
17
|
+
src/GPatch.egg-info/top_level.txt
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
LICENSE
|
|
2
|
-
MANIFEST.in
|
|
3
|
-
README.md
|
|
4
|
-
pyproject.toml
|
|
5
|
-
setup.py
|
|
6
|
-
./CODE_OF_CONDUCT.md
|
|
7
|
-
./LICENSE
|
|
8
|
-
./requirements.txt
|
|
9
|
-
GPatch.egg-info/PKG-INFO
|
|
10
|
-
GPatch.egg-info/SOURCES.txt
|
|
11
|
-
GPatch.egg-info/dependency_links.txt
|
|
12
|
-
GPatch.egg-info/entry_points.txt
|
|
13
|
-
GPatch.egg-info/not-zip-safe
|
|
14
|
-
GPatch.egg-info/requires.txt
|
|
15
|
-
GPatch.egg-info/top_level.txt
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|