miga-base 1.4.2.6 → 1.4.3.0
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.
- checksums.yaml +4 -4
- data/lib/miga/cli/action/preproc_wf.rb +20 -4
- data/lib/miga/result/stats.rb +14 -8
- data/lib/miga/version.rb +2 -2
- data/scripts/assembly.bash +6 -3
- data/scripts/trimmed_reads.bash +5 -2
- data/test/result_stats_test.rb +15 -1
- data/utils/multitrim/multitrim.py +63 -30
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 674190908d65b39a2a860c3f78c8f3449171ef5ce95005e6b36b008181db5530
|
|
4
|
+
data.tar.gz: 3f6c844d8a17d4c74bbe7d3a4df8cbae41d10d0263f42c34a0cd555de9164a70
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 445197498099f28214ba6a0876dd1dc51df8c568789b4e70678ef0b894f200001cde3e30ed3a6d5c2ea7856c7212e3ba5aa03e18b965294b70a71eec2bff958d
|
|
7
|
+
data.tar.gz: d665948deb9123884f9cc3774e51d36ac888eeb5c1fa877bd999ac1be643677c40371a70c075d91f38b043e08a49ec3d13eb3151d026ea1798d021c1e3bd5fa4
|
|
@@ -10,7 +10,7 @@ class MiGA::Cli::Action::PreprocWf < MiGA::Cli::Action
|
|
|
10
10
|
|
|
11
11
|
def parse_cli
|
|
12
12
|
default_opts_for_wf
|
|
13
|
-
cli.defaults = { mytaxa: false }
|
|
13
|
+
cli.defaults = { mytaxa: false, assembly: true }
|
|
14
14
|
cli.parse do |opt|
|
|
15
15
|
opt.on(
|
|
16
16
|
'-i', '--input-type STRING',
|
|
@@ -18,9 +18,13 @@ class MiGA::Cli::Action::PreprocWf < MiGA::Cli::Action
|
|
|
18
18
|
*MiGA::Cli::Action::Add.INPUT_TYPES.map { |k, v| "~ #{k}: #{v[0]}" }
|
|
19
19
|
) { |v| cli[:input_type] = v.downcase.to_sym }
|
|
20
20
|
opt.on(
|
|
21
|
-
'-m', '--
|
|
22
|
-
'Perform MyTaxa scan
|
|
21
|
+
'-m', '--mytaxa',
|
|
22
|
+
'Perform MyTaxa/MyTaxa scan analyses'
|
|
23
23
|
) { |v| cli[:mytaxa] = v }
|
|
24
|
+
opt.on(
|
|
25
|
+
'--no-assembly',
|
|
26
|
+
'Do not assemble the datasets or perform downstream analyses'
|
|
27
|
+
) { |v| cli[:assembly] = v }
|
|
24
28
|
opts_for_wf(
|
|
25
29
|
opt, 'Input files as defined by --input-type',
|
|
26
30
|
multi: true, cleanup: false, ncbi: false, project_type: true
|
|
@@ -36,14 +40,26 @@ class MiGA::Cli::Action::PreprocWf < MiGA::Cli::Action
|
|
|
36
40
|
]
|
|
37
41
|
p_metadata = Hash[norun.map { |i| ["run_#{i}", false] }]
|
|
38
42
|
d_metadata = { run_distances: false }
|
|
43
|
+
cli[:mytaxa] = false unless cli[:assembly]
|
|
39
44
|
unless cli[:mytaxa]
|
|
40
45
|
d_metadata[:run_mytaxa_scan] = false
|
|
41
46
|
d_metadata[:run_mytaxa] = false
|
|
42
47
|
end
|
|
48
|
+
unless cli[:assembly]
|
|
49
|
+
%w[assembly cds essential_genes ssu].each do |i|
|
|
50
|
+
d_metadata[:"run_#{i}"] = false
|
|
51
|
+
end
|
|
52
|
+
end
|
|
43
53
|
p = create_project(cli[:input_type], p_metadata, d_metadata)
|
|
44
54
|
|
|
45
55
|
# Run
|
|
46
56
|
run_daemon
|
|
47
|
-
|
|
57
|
+
summaries = []
|
|
58
|
+
if cli[:input_type].to_s =~ /^raw_reads_/
|
|
59
|
+
summaries += %w[raw_reads trimmed_reads]
|
|
60
|
+
end
|
|
61
|
+
summaries += %w[trimmed_fasta] if cli[:input_type].to_s =~ /^trimmed_reads_/
|
|
62
|
+
summaries += %w[cds assembly essential_genes ssu] if cli[:assembly]
|
|
63
|
+
summarize(summaries)
|
|
48
64
|
end
|
|
49
65
|
end
|
data/lib/miga/result/stats.rb
CHANGED
|
@@ -24,16 +24,18 @@ module MiGA::Result::Stats
|
|
|
24
24
|
|
|
25
25
|
private
|
|
26
26
|
|
|
27
|
-
def compute_stats_raw_reads
|
|
27
|
+
def compute_stats_raw_reads(format = :fastq)
|
|
28
28
|
stats = {}
|
|
29
29
|
seq_opts = { gc: true, x: true, skew: true }
|
|
30
30
|
if self[:files][:pair1].nil?
|
|
31
|
-
|
|
31
|
+
return {} if file_path(:single).nil?
|
|
32
|
+
s = MiGA::MiGA.seqs_length(file_path(:single), format, seq_opts)
|
|
32
33
|
stats = seqs_length_as_stats_hash(s)
|
|
33
34
|
else
|
|
34
35
|
stats = { read_pairs: nil }
|
|
35
36
|
{ pair1: :forward, pair2: :reverse }.each do |pair, direction|
|
|
36
|
-
|
|
37
|
+
return {} if file_path(pair).nil?
|
|
38
|
+
s = MiGA::MiGA.seqs_length(file_path(pair), format, seq_opts)
|
|
37
39
|
seqs_length_as_stats_hash(s).each do |k, v|
|
|
38
40
|
stats[k == :reads ? :read_pairs : :"#{direction}_#{k}"] ||= v
|
|
39
41
|
end
|
|
@@ -47,11 +49,15 @@ module MiGA::Result::Stats
|
|
|
47
49
|
end
|
|
48
50
|
|
|
49
51
|
def compute_stats_trimmed_fasta
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
if self[:files][:coupled].nil?
|
|
53
|
+
# Single- and separate paired-end reads
|
|
54
|
+
compute_stats_raw_reads(:fasta)
|
|
55
|
+
else
|
|
56
|
+
# Interleaved paired-end reads
|
|
57
|
+
f = file_path(:coupled)
|
|
58
|
+
s = MiGA::MiGA.seqs_length(f, :fasta, gc: true, x: true, skew: true)
|
|
59
|
+
seqs_length_as_stats_hash(s)
|
|
60
|
+
end
|
|
55
61
|
end
|
|
56
62
|
|
|
57
63
|
def compute_stats_assembly
|
data/lib/miga/version.rb
CHANGED
|
@@ -12,7 +12,7 @@ module MiGA
|
|
|
12
12
|
# - String indicating release status:
|
|
13
13
|
# - rc* release candidate, not released as gem
|
|
14
14
|
# - [0-9]+ stable release, released as gem
|
|
15
|
-
VERSION = [1.4,
|
|
15
|
+
VERSION = [1.4, 3, 0].freeze
|
|
16
16
|
|
|
17
17
|
##
|
|
18
18
|
# Nickname for the current major.minor version.
|
|
@@ -20,7 +20,7 @@ module MiGA
|
|
|
20
20
|
|
|
21
21
|
##
|
|
22
22
|
# Date of the current gem relese.
|
|
23
|
-
VERSION_DATE = Date.new(2026,
|
|
23
|
+
VERSION_DATE = Date.new(2026, 7, 22)
|
|
24
24
|
|
|
25
25
|
##
|
|
26
26
|
# References of MiGA
|
data/scripts/assembly.bash
CHANGED
|
@@ -52,12 +52,15 @@ CMD="spades.py -o $DATASET -t $CORES"
|
|
|
52
52
|
TYPE_OPT=""
|
|
53
53
|
case "$(miga ls -P "$PROJECT" -D "$DATASET" -m type | cut -f 2)" in
|
|
54
54
|
"metagenome")
|
|
55
|
+
# MetaSPADES doesn't support single-end metagenomes, so these datasets
|
|
56
|
+
# are instead treated as SAGs, which at least doesn't assume uniform
|
|
57
|
+
# coverage
|
|
55
58
|
TYPE_OPT="--meta" ;;
|
|
56
59
|
"plasmid")
|
|
57
60
|
TYPE_OPT="--plasmid" ;;
|
|
58
61
|
"scgenome")
|
|
59
62
|
TYPE_OPT="--sc" ;;
|
|
60
|
-
"genome")
|
|
63
|
+
"popgenome"|"genome")
|
|
61
64
|
TYPE_OPT="--isolate" ;;
|
|
62
65
|
"virome")
|
|
63
66
|
TYPE_OPT="--metaviral" ;;
|
|
@@ -69,7 +72,7 @@ if [[ -s "$F1" ]] ; then
|
|
|
69
72
|
CMD="$CMD -1 $F1 -2 $F2"
|
|
70
73
|
else
|
|
71
74
|
CMD="$CMD -s $F1"
|
|
72
|
-
[[ "$TYPE_OPT" == "--meta" ]] && TYPE_OPT=""
|
|
75
|
+
[[ "$TYPE_OPT" == "--meta" ]] && TYPE_OPT="--sc"
|
|
73
76
|
fi
|
|
74
77
|
else
|
|
75
78
|
F1="$TF/${DATASET}.CoupledReads.fa.gz"
|
|
@@ -78,7 +81,7 @@ else
|
|
|
78
81
|
CMD="$CMD --12 $F1"
|
|
79
82
|
elif [[ -s "$F2" ]] ; then
|
|
80
83
|
CMD="$CMD -s $F2"
|
|
81
|
-
[[ "$TYPE_OPT" == "--meta" ]] && TYPE_OPT=""
|
|
84
|
+
[[ "$TYPE_OPT" == "--meta" ]] && TYPE_OPT="--sc"
|
|
82
85
|
else
|
|
83
86
|
echo "No input files found to assemble" >&2
|
|
84
87
|
exit 1
|
data/scripts/trimmed_reads.bash
CHANGED
|
@@ -51,8 +51,11 @@ else
|
|
|
51
51
|
mv "$b/unpaired.post_trim_QC_${b}.1.html" \
|
|
52
52
|
"../03.read_quality/${b}.post.1.html"
|
|
53
53
|
fi
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
|
|
55
|
+
if [[ -e "$b/Subsample_Adapter_Detection.stats.txt" ]] ; then
|
|
56
|
+
mv "$b/Subsample_Adapter_Detection.stats.txt" \
|
|
57
|
+
"../03.read_quality/$b.adapters.txt"
|
|
58
|
+
fi
|
|
56
59
|
|
|
57
60
|
# Cleanup
|
|
58
61
|
rm -r "$b"
|
data/test/result_stats_test.rb
CHANGED
|
@@ -68,7 +68,7 @@ class ResultStatsTest < Test::Unit::TestCase
|
|
|
68
68
|
assert_equal({}, r.stats)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
def
|
|
71
|
+
def test_trimmed_fasta_interleaved
|
|
72
72
|
dir = 'data/04.trimmed_fasta'
|
|
73
73
|
fa = file_path(dir, '.CoupledReads.fa')
|
|
74
74
|
File.open(fa, 'w') { |fh| fh.puts '>1', 'ACTAC' }
|
|
@@ -80,6 +80,20 @@ class ResultStatsTest < Test::Unit::TestCase
|
|
|
80
80
|
assert_equal([40.0, '%'], r[:stats][:g_c_content])
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
+
def test_trimmed_fasta_separate
|
|
84
|
+
dir = 'data/04.trimmed_fasta'
|
|
85
|
+
[1, 2].each do |i|
|
|
86
|
+
fa = file_path(dir, ".#{i}.fasta")
|
|
87
|
+
File.open(fa, 'w') { |fh| fh.puts '>1', 'ACTAC' }
|
|
88
|
+
end
|
|
89
|
+
touch_done(dir)
|
|
90
|
+
r = dataset.add_result(:trimmed_fasta)
|
|
91
|
+
assert_equal({}, r[:stats])
|
|
92
|
+
r.compute_stats
|
|
93
|
+
assert_equal(1, r[:stats][:read_pairs])
|
|
94
|
+
assert_equal([40.0, '%'], r[:stats][:forward_g_c_content])
|
|
95
|
+
end
|
|
96
|
+
|
|
83
97
|
def test_assembly
|
|
84
98
|
# Prepare result
|
|
85
99
|
dir = 'data/05.assembly'
|
|
@@ -502,7 +502,13 @@ def adapter_identification_pe(artificial_artifacts, seqtk_binary, faqcs_binary,
|
|
|
502
502
|
ps = subprocess.Popen(faqcs_subset_command)
|
|
503
503
|
ps.wait()
|
|
504
504
|
|
|
505
|
-
os.
|
|
505
|
+
if os.path.exists(output + "/" + pdf_name):
|
|
506
|
+
os.remove(output + "/" + pdf_name)
|
|
507
|
+
|
|
508
|
+
# If no report can be found, assume no adapters
|
|
509
|
+
if not os.path.exists(output + "/" + prefix + "Subsample_Adapter_Detection.stats.txt"):
|
|
510
|
+
print("Nothing detected!")
|
|
511
|
+
return []
|
|
506
512
|
|
|
507
513
|
#Adapter detection from output of FaQCs
|
|
508
514
|
detection_report = open(output + "/" + prefix + "Subsample_Adapter_Detection.stats.txt")
|
|
@@ -527,7 +533,7 @@ def adapter_identification_pe(artificial_artifacts, seqtk_binary, faqcs_binary,
|
|
|
527
533
|
|
|
528
534
|
#Cleans up after itself.
|
|
529
535
|
for item in seqtk_samples:
|
|
530
|
-
os.remove(item)
|
|
536
|
+
if os.path.exists(item): os.remove(item)
|
|
531
537
|
|
|
532
538
|
print("Detection done!")
|
|
533
539
|
|
|
@@ -563,7 +569,13 @@ def adapter_identification_se(artificial_artifacts, seqtk_binary, faqcs_binary,
|
|
|
563
569
|
ps = subprocess.Popen(faqcs_subset_command)
|
|
564
570
|
ps.wait()
|
|
565
571
|
|
|
566
|
-
os.
|
|
572
|
+
if os.path.exists(output + "/" + pdf_name):
|
|
573
|
+
os.remove(output + "/" + pdf_name)
|
|
574
|
+
|
|
575
|
+
# If no report can be found, assume no adapters
|
|
576
|
+
if not os.path.exists(output + "/" + prefix + "Subsample_Adapter_Detection.stats.txt"):
|
|
577
|
+
print("Nothing detected!")
|
|
578
|
+
return []
|
|
567
579
|
|
|
568
580
|
#Adapter detection from output of FaQCs
|
|
569
581
|
detection_report = open(output + "/" + prefix + "Subsample_Adapter_Detection.stats.txt")
|
|
@@ -629,7 +641,7 @@ def parse_adapters(full_list, detected_adapters, output, prefix = ""):
|
|
|
629
641
|
|
|
630
642
|
subset.close()
|
|
631
643
|
|
|
632
|
-
return(output+"/"+ prefix + "detected_adapters.fasta")
|
|
644
|
+
return(output + "/" + prefix + "detected_adapters.fasta")
|
|
633
645
|
|
|
634
646
|
#paired end version of the full trim; trims using detected adapters with FaQCs -q 27, then fastp --cut_right window 3 qual 20
|
|
635
647
|
def full_trim_pe(forward_in, reverse_in, forward_out, reverse_out, directory, adapters, threads, faqcs, fastp, score, minlen, window, window_qual, prefix, compressor, compress_level, phred_fmt = "33", advanced = False, skip_fastp = False, skip_faqcs = False):
|
|
@@ -640,7 +652,7 @@ def full_trim_pe(forward_in, reverse_in, forward_out, reverse_out, directory, ad
|
|
|
640
652
|
Additionally, supports using only one of the two tools. Commands will be built even if the tool is to be skipped, but the call will never be issued.
|
|
641
653
|
'''
|
|
642
654
|
|
|
643
|
-
faqcs_command = [faqcs, "-t", str(threads), "-1", forward_in, "-2", reverse_in, "--artifactFile", adapters, "-q", str(score), "--min_L", str(minlen), "--prefix", "reads", "--trim_only", "-d", directory
|
|
655
|
+
faqcs_command = [faqcs, "-t", str(threads), "-1", forward_in, "-2", reverse_in, "--artifactFile", adapters, "-q", str(score), "--min_L", str(minlen), "--prefix", "reads", "--trim_only", "-d", directory]
|
|
644
656
|
fastp_command = [fastp, "--thread", str(threads), "--adapter_fasta", adapters, "-l", str(minlen), "--json", directory + "/" + prefix + "post_trim_fastp.json", "--html", directory + "/" + prefix + "post_trim_fastp.html"]
|
|
645
657
|
|
|
646
658
|
#Args can be added to fastp command with no consequences if fastp is skipped; command simply won't issue so they will be silent
|
|
@@ -653,9 +665,9 @@ def full_trim_pe(forward_in, reverse_in, forward_out, reverse_out, directory, ad
|
|
|
653
665
|
else:
|
|
654
666
|
#FaQCs goes first; this is how I coerce FaQCs reads to look afterwards
|
|
655
667
|
fastp_command.append("-i")
|
|
656
|
-
fastp_command.append(directory+"/reads.1.trimmed.fastq")
|
|
668
|
+
fastp_command.append(directory + "/reads.1.trimmed.fastq")
|
|
657
669
|
fastp_command.append("-I")
|
|
658
|
-
fastp_command.append(directory+"/reads.2.trimmed.fastq")
|
|
670
|
+
fastp_command.append(directory + "/reads.2.trimmed.fastq")
|
|
659
671
|
|
|
660
672
|
#Outputs are the same regardless of inputs
|
|
661
673
|
fastp_command.append("-o")
|
|
@@ -670,7 +682,9 @@ def full_trim_pe(forward_in, reverse_in, forward_out, reverse_out, directory, ad
|
|
|
670
682
|
fastp_command.append("--cut_right_mean_quality")
|
|
671
683
|
fastp_command.append(str(window_qual))
|
|
672
684
|
|
|
673
|
-
if phred_fmt != "33":
|
|
685
|
+
if phred_fmt != "33" and skip_faqcs:
|
|
686
|
+
# Only if skip_faqcs because FaQCs outputs ASCII 33 regardless
|
|
687
|
+
# of input format
|
|
674
688
|
fastp_command.append("--phred64")
|
|
675
689
|
|
|
676
690
|
if advanced:
|
|
@@ -685,15 +699,21 @@ def full_trim_pe(forward_in, reverse_in, forward_out, reverse_out, directory, ad
|
|
|
685
699
|
printable_time = timer.strftime(time_format)
|
|
686
700
|
print("Trimming with FaQCs. Started at:", printable_time)
|
|
687
701
|
subprocess.run(faqcs_command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
688
|
-
|
|
702
|
+
|
|
703
|
+
if os.path.exists(directory + "/" + "reads.stats.txt"):
|
|
704
|
+
os.remove(directory + "/" + "reads.stats.txt")
|
|
689
705
|
|
|
690
706
|
if not skip_fastp:
|
|
691
707
|
timer = datetime.now()
|
|
692
708
|
printable_time = timer.strftime(time_format)
|
|
693
709
|
print("Trimming with Fastp. Started at:", printable_time)
|
|
694
710
|
subprocess.run(fastp_command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
695
|
-
|
|
696
|
-
os.
|
|
711
|
+
|
|
712
|
+
if os.path.exists(directory + "/" + prefix + "post_trim_fastp.json"):
|
|
713
|
+
os.remove(directory + "/" + prefix + "post_trim_fastp.json")
|
|
714
|
+
|
|
715
|
+
if os.path.exists(directory + "/" + prefix + "post_trim_fastp.html"):
|
|
716
|
+
os.remove(directory + "/" + prefix + "post_trim_fastp.html")
|
|
697
717
|
|
|
698
718
|
|
|
699
719
|
|
|
@@ -703,7 +723,9 @@ def full_trim_pe(forward_in, reverse_in, forward_out, reverse_out, directory, ad
|
|
|
703
723
|
#rename FaQCs files to correct names; compress
|
|
704
724
|
|
|
705
725
|
#remove this one in any event. We don't want any unpaireds with paired end
|
|
706
|
-
os.
|
|
726
|
+
if os.path.exists(directory + "/reads.unpaired.trimmed.fastq"):
|
|
727
|
+
os.remove(directory + "/reads.unpaired.trimmed.fastq")
|
|
728
|
+
|
|
707
729
|
shutil.move(directory+"/reads.1.trimmed.fastq", forward_out)
|
|
708
730
|
shutil.move(directory+"/reads.2.trimmed.fastq", reverse_out)
|
|
709
731
|
#compress_commands = [[directory+"/reads.1.trimmed.fastq", forward_out], [directory+"/reads.2.trimmed.fastq", reverse_out]]
|
|
@@ -714,10 +736,15 @@ def full_trim_pe(forward_in, reverse_in, forward_out, reverse_out, directory, ad
|
|
|
714
736
|
|
|
715
737
|
elif not skip_faqcs:
|
|
716
738
|
#remove FaQCs files if fastp has results or skip if FaQCs not done.
|
|
717
|
-
os.
|
|
718
|
-
|
|
739
|
+
if os.path.exists(directory + "/reads.1.trimmed.fastq"):
|
|
740
|
+
os.remove(directory + "/reads.1.trimmed.fastq")
|
|
741
|
+
|
|
742
|
+
if os.path.exists(directory + "/reads.2.trimmed.fastq"):
|
|
743
|
+
os.remove(directory + "/reads.2.trimmed.fastq")
|
|
744
|
+
|
|
719
745
|
#remove this one in any event. We don't want any unpaireds with paired end - the call has to be duplicated, unfortunately.
|
|
720
|
-
os.
|
|
746
|
+
if os.path.exists(directory + "/reads.unpaired.trimmed.fastq"):
|
|
747
|
+
os.remove(directory + "/reads.unpaired.trimmed.fastq")
|
|
721
748
|
|
|
722
749
|
compress_results([forward_out, reverse_out], threads, compressor, compress_level)
|
|
723
750
|
|
|
@@ -731,7 +758,7 @@ def full_trim_se(reads_in, reads_out, directory, adapters, threads, faqcs, fastp
|
|
|
731
758
|
The primary purpose is to issue a FaQCs call on the untrimmed reads, then a subsequent fastp call on the outputs from the FaQCs call.
|
|
732
759
|
Additionally, supports using only one of the two tools. Commands will be built even if the tool is to be skipped, but the call will never be issued.
|
|
733
760
|
'''
|
|
734
|
-
faqcs_command = [faqcs, "-t", str(threads), "-u", reads_in, "--artifactFile", adapters, "-q", str(score), "--min_L", str(minlen), "--prefix", "reads", "--trim_only", "-d", directory
|
|
761
|
+
faqcs_command = [faqcs, "-t", str(threads), "-u", reads_in, "--artifactFile", adapters, "-q", str(score), "--min_L", str(minlen), "--prefix", "reads", "--trim_only", "-d", directory]
|
|
735
762
|
fastp_command = [fastp, "--thread", str(threads), "--adapter_fasta", adapters, "-l", str(minlen), "--json", directory + "/" + prefix + "post_trim_fastp.json", "--html", directory + "/" + prefix + "post_trim_fastp.html"]
|
|
736
763
|
|
|
737
764
|
#Args can be added to fastp command with no consequences if fastp is skipped; command simply won't issue so they will be silent
|
|
@@ -742,7 +769,7 @@ def full_trim_se(reads_in, reads_out, directory, adapters, threads, faqcs, fastp
|
|
|
742
769
|
else:
|
|
743
770
|
#FaQCs goes first; this is how I coerce FaQCs reads to look afterwards
|
|
744
771
|
fastp_command.append("-i")
|
|
745
|
-
fastp_command.append(directory+"/reads.unpaired.trimmed.fastq")
|
|
772
|
+
fastp_command.append(directory + "/reads.unpaired.trimmed.fastq")
|
|
746
773
|
|
|
747
774
|
#Outputs are the same regardless of inputs
|
|
748
775
|
fastp_command.append("-o")
|
|
@@ -755,7 +782,9 @@ def full_trim_se(reads_in, reads_out, directory, adapters, threads, faqcs, fastp
|
|
|
755
782
|
fastp_command.append("--cut_right_mean_quality")
|
|
756
783
|
fastp_command.append(str(window_qual))
|
|
757
784
|
|
|
758
|
-
if phred_fmt != "33":
|
|
785
|
+
if phred_fmt != "33" and skip_faqcs:
|
|
786
|
+
# Only if skip_faqcs because FaQCs outputs ASCII 33 regardless
|
|
787
|
+
# of input format
|
|
759
788
|
fastp_command.append("--phred64")
|
|
760
789
|
|
|
761
790
|
if advanced:
|
|
@@ -770,24 +799,30 @@ def full_trim_se(reads_in, reads_out, directory, adapters, threads, faqcs, fastp
|
|
|
770
799
|
printable_time = timer.strftime(time_format)
|
|
771
800
|
print("Trimming with FaQCs. Started at:", printable_time)
|
|
772
801
|
subprocess.run(faqcs_command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
773
|
-
|
|
802
|
+
|
|
803
|
+
if os.path.exists(directory + "/" + "reads.stats.txt"):
|
|
804
|
+
os.remove(directory + "/" + "reads.stats.txt")
|
|
774
805
|
|
|
775
806
|
if not skip_fastp:
|
|
776
807
|
timer = datetime.now()
|
|
777
808
|
printable_time = timer.strftime(time_format)
|
|
778
809
|
print("Trimming with Fastp. Started at:", printable_time)
|
|
779
810
|
subprocess.run(fastp_command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
780
|
-
|
|
781
|
-
os.
|
|
811
|
+
|
|
812
|
+
if os.path.exists(directory + "/" + prefix + "post_trim_fastp.json"):
|
|
813
|
+
os.remove(directory + "/" + prefix + "post_trim_fastp.json")
|
|
814
|
+
|
|
815
|
+
if os.path.exists(directory + "/" + prefix + "post_trim_fastp.html"):
|
|
816
|
+
os.remove(directory + "/" + prefix + "post_trim_fastp.html")
|
|
782
817
|
|
|
783
818
|
|
|
784
819
|
if skip_fastp:
|
|
785
820
|
#compress the result
|
|
786
821
|
#remove this one in any event. We don't want any unpaireds with paired end
|
|
787
|
-
shutil.move(directory+"/reads.unpaired.trimmed.fastq", reads_out)
|
|
788
|
-
elif not skip_faqcs:
|
|
822
|
+
shutil.move(directory + "/reads.unpaired.trimmed.fastq", reads_out)
|
|
823
|
+
elif not skip_faqcs and os.path.exists(directory + "/reads.unpaired.trimmed.fastq"):
|
|
789
824
|
#remove FaQCs files if fastp has results or skip if FaQCs not run.
|
|
790
|
-
os.remove(directory+"/reads.unpaired.trimmed.fastq")
|
|
825
|
+
os.remove(directory + "/reads.unpaired.trimmed.fastq")
|
|
791
826
|
|
|
792
827
|
compress_results([reads_out], threads, compressor, compress_level)
|
|
793
828
|
|
|
@@ -959,7 +994,7 @@ def pretty_print_file_size(name, start, end, start_time, end_time):
|
|
|
959
994
|
|
|
960
995
|
runtime = '%02d:%02d:%02d' % (hours, minutes, seconds)
|
|
961
996
|
|
|
962
|
-
print(name, "compressed! Compression took:", runtime
|
|
997
|
+
print(name, "compressed! Compression took:", runtime)
|
|
963
998
|
|
|
964
999
|
return None
|
|
965
1000
|
|
|
@@ -1254,8 +1289,7 @@ def main():
|
|
|
1254
1289
|
adapters_detected = adapter_identification_pe(complete_adapter_file_name, stk, fq, f, r, threads, final_output, minpres, prefix, phred)
|
|
1255
1290
|
cleaned_adapters = parse_adapters(adapter_set, adapters_detected, final_output, prefix)
|
|
1256
1291
|
|
|
1257
|
-
if needs_cleanup:
|
|
1258
|
-
print("Removing automatically generated adapters...")
|
|
1292
|
+
if needs_cleanup and os.path.exists(complete_adapter_file_name):
|
|
1259
1293
|
os.remove(complete_adapter_file_name)
|
|
1260
1294
|
|
|
1261
1295
|
full_trim_pe(f, r, post_trim_f, post_trim_r, final_output, cleaned_adapters, threads, fq, fp, score, minlen, mid, mid_q, prefix, compressor, compression_level, phred, advanced, skip_fp, skip_fq)
|
|
@@ -1274,8 +1308,7 @@ def main():
|
|
|
1274
1308
|
adapters_detected = adapter_identification_se(complete_adapter_file_name, stk, fq, u, threads, final_output, minpres, prefix, phred)
|
|
1275
1309
|
cleaned_adapters = parse_adapters(adapter_set, adapters_detected, final_output, prefix)
|
|
1276
1310
|
|
|
1277
|
-
if needs_cleanup:
|
|
1278
|
-
print("Removing automatically generated adapters...")
|
|
1311
|
+
if needs_cleanup and os.path.exists(complete_adapter_file_name):
|
|
1279
1312
|
os.remove(complete_adapter_file_name)
|
|
1280
1313
|
|
|
1281
1314
|
full_trim_se(u, post_trim, final_output, cleaned_adapters, threads, fq, fp, score, minlen, mid, mid_q, prefix, compressor, compression_level, phred, advanced, skip_fp, skip_fq)
|
|
@@ -1561,4 +1594,4 @@ def create_seq_to_fam():
|
|
|
1561
1594
|
|
|
1562
1595
|
|
|
1563
1596
|
|
|
1564
|
-
os.remove(name)
|
|
1597
|
+
if os.path.exists(name): os.remove(name)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: miga-base
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.4.
|
|
4
|
+
version: 1.4.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Luis M. Rodriguez-R
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-07-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: daemons
|